1

自从将我们的项目更新到 Visual Studio 2012 并从 4.0 面向 .NET 框架 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, Culture= 类型的对象时出错中性,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 时,有没有人遇到过类似的情况?

任何回应都非常感谢,--肖恩

4

1 回答 1

0

您能否尝试公开另一个返回与 GetPreviousPage 返回相同数据但将 ResponseFormat 更改为 Xml 的函数?然后多次调用它(例如从浏览器),看看这个新功能是否会失败。这很好地帮助您了解问题是否与 Json 序列化程序有关。

[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "/Pages/Site/ListItemsNew/{siteId}",
BodyStyle = WebMessageBodyStyle.Bare),
Description("")]
IEnumerable<PageInfoItem> GetPreviousPagesNew(string siteId);

PS:将此作为答案发布,因为很难在评论中发布代码。

于 2013-03-07T20:22:14.600 回答