WebService不反序列化某些对象
我已经建立了一个Web服务(REST),我从Windows服务中调用它。
有些电话似乎没有问题,也有问题。 而其他一些人正在返回Bad Request。 我将服务器设置为在反序列化数据为NULL时返回Bad Request。
Web Service使用EDMX从数据库生成对象类。
本地服务具有对Web服务的服务引用,因此它具有相同的对象类。
我正在使用Microsoft.AspNet.WebApi.Client Nuget Package来从本地服务进行调用。
代码低于Web服务操作
//NOT WORKING [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "{entity}/consent/{consent_id}/info")] bool ConsentInformation(string entity, string consent_id, consent info); //WORKING [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "{entity}/council/users")] void GoGetUsers(string entity, IEnumerable user);
WEB服务代码
//NOT WORKING public void ConsentStatus(string entity, string consent_id, consent_status status) { Utilities.SetResponseFormat(); if (status == null) { WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest; return; } gosubmitEntity entitys = new gosubmitEntity(); consent_status consent = entitys.consent_status.FirstOrDefault(c => c.consent_id == consent_id && c.council_code == entity); if (consent == null) entitys.consent_status.Add(status); else consent = status; entitys.SaveChanges(); WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Created; } //WORKING public void GoGetUsers(string entity, IEnumerable users) { Utilities.SetResponseFormat(); if (users == null || users.Count() == 0) { WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest; return; } gosubmitEntity entitys = new gosubmitEntity(); foreach (council_user user in users) { council_user dbUser = entitys.council_user.FirstOrDefault(u => u.username == user.username && u.council_code == entity); if (dbUser == null) entitys.council_user.Add(user); else dbUser = user; } entitys.SaveChanges(); }
本地服务代码
public static async Task POST(string requestURI, T data) { HttpClient client = CreateClient(); HttpResponseMessage response = await client.PostAsJsonAsync(requestURI, data); if (response.IsSuccessStatusCode) return true; else { DiagnosticLog.Write(99, $"Status response from webservice = {response.StatusCode}", string.Empty); return false; } } private static HttpClient CreateClient() { var client = new HttpClient(); client.BaseAddress = new Uri(Settings.BaseWebservice); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); return client; }
不工作的对象类
public partial class consent_status { public string consent_id { get; set; } public string council_code { get; set; } public string lodged { get; set; } public string processing { get; set; } public string rfis { get; set; } public string issued { get; set; } public string inspections { get; set; } public string ccc { get; set; } public Nullable date_lodged { get; set; } public Nullable date_granted { get; set; } public Nullable date_issued { get; set; } public Nullable date_cccissued { get; set; } public Nullable days_live { get; set; } public Nullable days_inactive { get; set; } public Nullable days_suspended { get; set; } public Nullable form6_received { get; set; } public string ccc_file_name { get; set; } public Nullable last_updated { get; set; } }
POST数据示例
{"ccc":"","ccc_file_name":"","consent_id":"120266","council_code":"DEMO","date_cccissued":null,"date_granted":null,"date_issued":null,"date_lodged":"2012-05-03T00:00:00","days_inactive":null,"days_live":null,"days_suspended":null,"form6_received":null,"inspections":"In Progress","issued":"","last_updated":null,"lodged":"Accepted","processing":"","rfis":"Pending"}
任何想法将不胜感激。
谢谢
您的问题是您使用的两种技术WCF Rest和HttpClient.PostAsJsonAsync()
使用不同的序列化程序。 WCF Rest使用DataContractJsonSerializer
而PostAsJsonAsync
内部使用默认使用Json.NET的 JsonMediaTypeFormatter
。
而且,遗憾的是,这两个序列化程序对日期具有不同的默认格式(请记住, JSON中没有日期的标准表示 ):
- 在Json.NET中,您的日期序列化为ISO 8601标准字符串
"date_lodged": "2012-05-03T00:00:00"
。 - 使用数据协定序列化程序,它使用特殊的Microsoft格式
"date_lodged":"\/Date(1336017600000-0400)\/"
。
因此,当WCFrest服务在内部使用的DataContractJsonSerializer
尝试反序列化日期时,它会失败并引发exception。
您有几个选项可以解决此问题。
首先,您可以配置WCFrest以使用不同的序列化程序。 这涉及到,请参阅WCF可扩展性 – 消息格式化程序和WCF“原始”编程模型(Web) 。
其次,您可以使用数据协定序列化程序使客户端序列化。 这很简单,只需设置JsonMediaTypeFormatter.UseDataContractJsonSerializer = true
。 我相信以下扩展应该做的工作:
public static class HttpClientExtensions { public static Task PostAsDataContractJsonAsync(this HttpClient client, string requestUri, T value) { return client.PostAsJsonAsync(requestUri, value, CancellationToken.None); } public static Task PostAsDataContractJsonAsync(this HttpClient client, string requestUri, T value, CancellationToken cancellationToken) { return client.PostAsync(requestUri, value, new JsonMediaTypeFormatter { UseDataContractJsonSerializer = true }, cancellationToken); } }
或者您可以在客户端坚持使用Json.NET 并将默认日期格式更改为Microsoft格式:
public static class HttpClientExtensions { public static Task PostAsJsonAsync(this HttpClient client, string requestUri, T value, JsonSerializerSettings settings) { return client.PostAsJsonAsync(requestUri, value, settings, CancellationToken.None); } public static Task PostAsJsonAsync(this HttpClient client, string requestUri, T value, JsonSerializerSettings settings, CancellationToken cancellationToken) { return client.PostAsync(requestUri, value, new JsonMediaTypeFormatter { SerializerSettings = settings }, cancellationToken); } }
使用设置
settings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat };
或者,您可以修改客户端以使用REST服务,这与使用REST服务和.NET以及解析REST服务JSON响应(C#)一致 。
最后,您还可以考虑切换到在服务器端使用Json.NET的 ASP.NET Web API 。