【发布时间】:2013-03-07 19:19:11
【问题描述】:
自从将我们的项目更新到 Visual Studio 2012 并从 4.0 面向 .NET Framework 4.5 以来,我们在尝试从我们的服务方法返回数据时间歇性地遇到序列化异常问题,但出于调试问题的目的,我们'我们将注意力集中在单一服务方法 GetPageSelectListForSite。
这个方法接口声明如下:
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "/Pages/Site/ListItems/{siteId}",
BodyStyle = WebMessageBodyStyle.Bare),
Description("")]
IEnumerable<PageInfoItem> GetPreviousPages(string siteId);
使用相同的签名参数调用,并且在控制器内部返回相同的IEnumerable数据;但是,偶尔(每 100 次左右)这会在控制器尝试反序列化 REST 服务回复时导致序列化异常:
System.Runtime.Serialization.SerializationException:反序列化 System.Collections.Generic.IEnumerable`1[[Synodine.Hkd.Models.PageInfoItem, Synodine.Hkd.Models, Version= 类型的对象时出错1.0.0.0,文化=中性,PublicKeyToken=null]]。遇到意外的字符“D”。 ---> System.Xml.XmlException: 遇到意外字符“D”。
完整的异常和相应的堆栈跟踪可在此处获得: http://pastebin.com/jaqQDbru
PageInfoItem 是一个包含字符串的相当简单的类,它派生自 ListInfoBase,其中包含一个 guid、一些字符串、一些布尔值和一个 DateTime。
尝试使用 [Serializable] AND/OR [DataContract]/[DataMember] 装饰类没有任何效果。我们无法始终如一地重现该问题。
我应该注意到,我们已经看到序列化异常错误发生在一个极其简单的 REST GET 方法上,响应/请求格式设置为 Json,Bare 的 BodyStyle 返回单个字符串。所讨论的其余服务方法是 POST/GET 还是其样式设置为 Bare 或 Wrapped 似乎并不重要,尽管在所有情况下我们都在使用 WebMessageFormat.Json。
我们已经尝试自己序列化数据并记录它以查看 JSON 是否以某种方式格式错误,但 JSON 是有效的,并且在失败/成功的请求中是相同的。
这是我们用来序列化数据的代码:
var stream1 = new MemoryStream();
var ser = new DataContractJsonSerializer(typeof(IEnumerable<PageInfoItem>));
ser.WriteObject(stream1, PageInfoItems);
stream1.Position = 0;
var streamReader = new StreamReader(stream1);
正在记录的 JSON 示例是:
[
{
"DateLastUpdate": "\/Date(1362438368000+0000)\/",
"DateLastUpdateString": null,
"Id": "df2544e6-71a3-4f1c-ac54-d3c85269804f",
"IsSelected": false,
"Name": "samplepage",
"Path": "\/samplepage"
},
<snip>
]
这个问题只发生在我们部署的环境中。在我们的本地 IIS 网络服务器上重现该问题的所有尝试都失败了。
我们正在使用 WebChannelFactory 来使用 WCF REST 服务。因此,我们没有(也不确定如何获得)直接访问响应的权限,因此我们无法 100% 地通过网络发送数据。
有人在将项目升级到 Visual Studio 2012/.NET 4.5 Framework 时遇到过类似情况吗?
任何回复都非常感谢, -- 肖恩
【问题讨论】:
-
这是 SO 遗漏的,一个真正的问题,而且解释得很好。 :)
-
您返回的数据有多大。大小可能是问题吗?
-
谢谢!它相当小,在我们的测试过程中,我们确保调用与从 REST 方法返回的数据相同,在对其使用 DataContractJsonSerializer 后为 1320 字节,假设 ChannelFactory 在转换时使用标准的 .NET DataContractJsonSerializer传递到 JSON 之前。
-
当一个 GET 失败时(例如 /Pages/Site/ListItems/3),如果你再次重试相同的 URL,它会再次失败吗?
-
这就是令人沮丧的事情,刷新对访问控制器的相同 URL 调用完全相同的服务方法和完全相同的数据集将在下一次成功。
标签: c# asp.net json rest exception