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使用DataContractJsonSerializerPostAsJsonAsync内部使用默认使用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 。