我有一项服务,其中操作合同如下所示。我有一个WebInvoke属性,该方法设置为POST。我有一个UriTemplate。实际的服务方法名称是SaveUser。我试图传入一个User对象(一个带有注释为数据成员属性的属性的数据协定)。
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "SaveUser", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json)]
User SaveUser(User user);
客户端如下所示。为简单起见,我已经排除了令牌和授权等。:
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());
}
}
}
问题:服务方法(实际服务)正在接收param(User)为NULL。我究竟做错了什么?我尝试在服务合同中添加已知类型,但没有运气。
答案 0 :(得分:2)
您的问题是您将操作定义为包装请求。这意味着该参数不是作为“普通”JSON对象发送,而是必须包装在JSON对象中,并且成员名称必须对应于参数名称(在您的情况下为user
)。下面的代码包装;你可以看到,现在服务器正确接收了参数。另一种选择是将BodyStyle
属性更改为Bare
而不是WrappedRequest
(在这种情况下,您需要将 plain 对象发送到服务运营)。
public class StackOverflow_12452466
{
[ServiceContract]
public interface ITest
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "SaveUser", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json)]
User SaveUser(User user);
}
public class Service : ITest
{
public User SaveUser(User user)
{
Console.WriteLine("User: {0}", user);
return user;
}
}
public class User
{
public string UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string LoginName { get; set; }
public string Password { get; set; }
public string PayPalEmailAddress { get; set; }
public string PhoneNumber { get; set; }
public override string ToString()
{
return string.Format("Id={0},First={1},Last={2},Login={3},Pwd={4},PayPal={5},Phone={6}",
UserId, FirstName, LastName, LoginName, Password, PayPalEmailAddress, PhoneNumber);
}
}
public static void Test()
{
string serviceBaseUrl = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(serviceBaseUrl));
host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
host.Open();
Random r = new Random();
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 webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json; charset=utf-8";
Func<byte[], string> ByteArrayToString = (b) => Encoding.UTF8.GetString(b);
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(User));
try
{
using (var memStream = new MemoryStream())
{
byte[] wrappingStart = Encoding.UTF8.GetBytes("{\"user\":");
memStream.Write(wrappingStart, 0, wrappingStart.Length);
ser.WriteObject(memStream, u);
byte[] wrappingEnd = Encoding.UTF8.GetBytes("}");
memStream.Write(wrappingEnd, 0, wrappingEnd.Length);
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());
}
}
}
}