С момента обновления нашего проекта до Visual Studio 2012 и ориентации .NET Framework 4.5 из 4.0 мы периодически сталкивались с проблемами исключения сериализации при попытке вернуть данные из нашей службы методы, хотя для отладки проблемы мы сосредоточили наше внимание на одном методе сервиса GetPageSelectListForSite.Ошибки прерывистой десериализации в REST WCF Service в .NET 4.5
Эта декларация интерфейса методы заключается в следующем:
[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 = neutral, PublicKeyToken = null]]. Обнаружен неожиданный символ «D». ---> System.Xml.XmlException: обнаружен неожиданный символ «D».
Полное исключение и соответствующая трассировка стека доступна здесь: http://pastebin.com/jaqQDbru
PageInfoItem является довольно простой класс, содержащий строку, и выводит из ListInfoBase, который содержит GUID, некоторые строки, некоторые BOOLS, и DateTime ,
Попытки украсить классы с помощью [Serializable] AND/OR [DataContract]/[DataMember] не повлияли. Мы не смогли последовательно воспроизвести проблему.
Следует отметить, что мы видели ошибку исключения сериализации в чрезвычайно простом методе REST GET, с форматами ответа/запроса, установленными в Json и BodyStyle of Bare, который возвращает одну строку. Кажется, что не имеет значения, является ли метод обслуживания rest, 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. Из-за этого у нас нет (и не уверены, как получить) прямой доступ к Response, поэтому мы не можем быть на 100% от данных, передаваемых по кабелю.
Кто-нибудь сталкивался с чем-то похожим на это при обновлении своих проектов в Visual Studio 2012/.NET 4.5 Framework?
Любые ответы, безусловно, оценили, - Shaun
Это то, что так скучает, настоящая проблема и очень хорошо объясненный вопрос. :) – publicgk
Насколько велики ваши возвращенные данные. Может ли проблема быть проблемой? – publicgk
Спасибо! Это довольно мало, во время тестирования мы убедились, что вызов идентичен вместе с данными, которые возвращаются из метода REST, это 1320 байт после использования DataContractJsonSerializer на нем, предполагая, что ChannelFactory использует стандартный .NET DataContractJsonSerializer при его преобразовании до JSON, прежде чем передать его по проводам. – zoombini