I have a service where the operation contract looks like the following. I have a WebInvoke attribute and the method is set to POST. I do have a UriTemplate. The actual service method name is SaveUser. I am trying to pass in a User object (a data contract with properties annotated as data member attributes).
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "SaveUser", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json)]
User SaveUser(User user);
The client looks like the following. For simplicity I have excluded the token and authorization etc.:
using (WebClient webClient = new WebClient())
{
try
{
Random r = new Random();
var partitionKey = Guid.NewGuid().ToString();
var rowKey = r.Next(999900, 999999).ToString();
User u = new User()
{
UserId = partitionKey,
FirstName = "First-" + DateTime.Now.Ticks.ToString(),
LastName = "Last-" + DateTime.Now.Ticks.ToString(),
LoginName = rowKey,
Password = "password1",
PayPalEmailAddress = "First" + DateTime.Now.Ticks.ToString() + "@verascend.com",
PhoneNumber = "+1206" + r.Next(1234567, 9999999).ToString()
};
string url = serviceBaseUrl + "/SaveUser";
webClient.Headers["Content-type"] = "application/json; charset=utf-8";
// webClient.Headers[HttpRequestHeader.Authorization] = authToken;
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(User));
using (var memStream = new MemoryStream())
{
ser.WriteObject(memStream, u);
Debug.WriteLine("-------------> "+ByteArrayToString(memStream.ToArray()));
webClient.UploadData(url, "POST", memStream.ToArray());
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
string responseText = string.Empty;
using (Stream responseStream = ((HttpWebResponse)ex.Response).GetResponseStream())
{
using (StreamReader streamReader = new StreamReader(responseStream))
{
responseText = streamReader.ReadToEnd();
}
}
throw new Exception(responseText);
}
else
{
throw new Exception(ex.Message.ToString());
}
}
}
Problem: The service method (actual service) is receiving the param (User) as NULL. What am I doing wrong? I tried adding the known type in the service contract but no luck.
Your problem is that you define your operation to have a wrapped request. That means that the parameter, instead of being sent as a "plain" JSON object, must be wrapped in a JSON object, and the member name must correspond to the parameter name (in your case,
user
). The code below does the wrapping; you can see that with that the parameter now is properly received by the server. Another option would be to change theBodyStyle
property toBare
instead ofWrappedRequest
as you have (in which case you'd need to send the plain object to the service operation).