2013-01-08 182 views
0

我正在使用SignalR从客户端发布一个对象到服务器,该对象包含一个日期属性,有时具有UTC日期时间,有时是本地日期时间(本身是一个单独的问题)。我注意到的是,只要日期是当地时间,例如'2013-01-08T10:35:59.8484157 + 00:00'我得到'无法将字符串转换为DateTime'错误。在检查时,似乎试图解析的字符串已经从导致转换错误的时区偏移信息中丢失了“+”字符。我想了解这个角色是如何失去的。SignalR日期时间反序列化错误

SignalR正确序列化对象到JSON,和编码它,如+字符被编码为%2B作为可以在SignalR请求

data=%7B%22H%22%3A%22alertshub%22%2C%22M%22%3A%22AcknowledgeAlert%22%2C%22A%22%3A%5B%7B%22Id%22%3A%22e2d65f79-6a03-4094-a00f-99fcd9b46a7a%22%2C%22StartDateTimeUtc%22%3A%222013-01-08T10%3A26%3A44.0849463%2B00%3A00%22%2C%22EndDateTimeUtc%22%3Anull%2C%22AcknowledgedDateTimeUtc%22%3Anull%2C%22Description%22%3A%22Test+Alert+17%22%7D%5D%2C%22I%22%3A0%7D 

经由UrlDecode功能运行此的主体中可以看出返回正确的值

data={ 
    "H":"alertshub", 
    "M":"AcknowledgeAlert", 
    "A":[{ 
      "Id":"e2d65f79-6a03-4094-a00f-99fcd9b46a7a", 
      "StartDateTimeUtc":"2013-01-08T10:26:44.0849463+00:00", 
      "EndDateTimeUtc":null, 
      "AcknowledgedDateTimeUtc":null, 
      "Description":"Test Alert 17" 
    }], 
    "I":0 
} 

但是,在查看SignalR请求上下文时,主体已列出'+',现在是空格。这会导致日期转换错误。看来在SignalR/JSON.NET/.NET这一行的某个地方(不知道哪一个)会对发布的数据进行双重解码并将+转换为空间。

我创建了一个简单的MVC应用程序,它演示了这个问题,其高达GitHub上http://github.com/davidthompson/SignalRPlusEncodingTest

一旦样本应用程序运行时点击确认按钮旁边的任何警报与UTC日起,这将调用一个SignalR方法在集线器上并且警报将消失。如果您对具有本地日期的警报执行相同的操作,它将会失败(单击“创建新警报”按钮,它会随机生成一个带有UTC或LOCAL日期的警报)。浏览器控制台将显示有关转换失败的错误。但在这种情况下,确实没有收到下面的错误是:

[10:36:04 GMT+0000 (GMT Standard Time)] SignalR: Could not convert string to DateTime: 2013-01-08T10:35:53.1401147 00:00. Path 'StartDateTimeUtc', line 1, position 144. 
    at Newtonsoft.Json.JsonReader.ReadAsDateTimeInternal() 
    at Newtonsoft.Json.Linq.JTokenReader.ReadAsDateTime() 
    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) 
    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) 
    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) 
    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) 
    at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) 
    at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) 
    at Microsoft.AspNet.SignalR.JTokenValue.ConvertTo(Type type) 
    at Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver.ResolveParameter(ParameterDescriptor descriptor, IJsonValue value) 
    at System.Linq.Enumerable.<ZipIterator>d__7a`3.MoveNext() 
    at System.Linq.Buffer`1..ctor(IEnumerable`1 source) 
    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 
    at Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver.ResolveMethodParameters(MethodDescriptor method, IJsonValue[] values) 
    at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.InvokeHubPipeline(IHub hub, IJsonValue[] parameterValues, MethodDescriptor methodDescriptor, HubRequest hubRequest, StateChangeTracker tracker) 

jquery....min.js (line 10) 

在此先感谢

回答