2013-03-07 10 views
1

С момента обновления нашего проекта до 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

+0

Это то, что так скучает, настоящая проблема и очень хорошо объясненный вопрос. :) – publicgk

+0

Насколько велики ваши возвращенные данные. Может ли проблема быть проблемой? – publicgk

+0

Спасибо! Это довольно мало, во время тестирования мы убедились, что вызов идентичен вместе с данными, которые возвращаются из метода REST, это 1320 байт после использования DataContractJsonSerializer на нем, предполагая, что ChannelFactory использует стандартный .NET DataContractJsonSerializer при его преобразовании до JSON, прежде чем передать его по проводам. – zoombini

ответ

0

Вы можете попробовать подвергая другую функцию, которая возвращать те же данные, что GetPreviousPage возвращается, но изменения ResponseFormat сказать Xml? Затем вызовите его несколько раз (например, из браузера) и посмотрите, не сработала ли эта новая функция . Это поможет вам узнать, есть ли проблема с Json Serializer.

[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: Отправлено это как ответ, так как это сложно опубликовать в комментарии.

+0

Привет, publicgk, Xml, похоже, устранил проблему, к сожалению, переработав все методы сервиса REST для XML, потребуется серьезная переписывание. РЕДАКТИРОВАТЬ: Сервер оказался в стороне от обновлений и пакетов обновления. После того, как мы обновили, проблема исчезла. Урок выучен. Спасибо за помощь, определенно оцените! – zoombini