Служба WCF, сериализация Json и поиск ошибок

#ajax #wcf #json

#ajax #wcf #json

Вопрос:

Допустим, у меня есть простой сервис WCF:

 [ServiceContract]
public interface ITestService
{
    [OperationContract]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
    object Operation();
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService : ITestService
{
    public object Operation()
    {
          return /*some object*/
    }
}
  

и страница aspx, которая выполняет ajax-вызов этой службы и использует возвращаемый объект, вот вызов ajax:

 $.ajax({
    type: "POST",
    url: "TestService.svc/Operation",
    async: false,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    processdata: true,
    success: function (msg) {
     var res = msg.OperationResu<
    },
    error: function (xhr, msg, thrown) {
     var error = xhr;
    }
});
  

Если операция () возвращает простой объект, такой как строка или число, тогда сообщение об ошибке.OperationResult возвращает этот объект, ошибка не выдается, все работает нормально.
Однако, если я попытаюсь вернуть сложный объект, который имеет общедоступные и внутренние свойства общедоступных и внутренних ссылочных типов, тогда msg.Результат операции, переданный при успешном обратном вызове, не определен. обратный вызов с ошибкой не вызван. Похоже, что WCF пытается сериализовать сложный объект, сталкивается с ошибкой и просто возвращает null вместо того, чтобы выдавать исключение.
Вопрос в том, как я могу обрабатывать ошибки такого типа? Какой сериализатор используется WCF внутренне? Является ли это DataContractJsonSerializer?

Ответ №1:

  1. да, используется DataContractJsonSerializer.
  2. WCF будет сериализовывать только те типы, о которых он знает. Вы объявили возвращаемый тип как object , поэтому он сможет возвращать только любые экземпляры System.Объект или примитивные типы, которые всегда известны WCF (такие как числа, строки, дата-время и т.д.). Если вам нужно вернуть сложный тип, вам нужно объявить его как известный тип в контракте, как показано ниже.

Контракт с объявлением для известного типа. Для получения дополнительной информации смотрите документацию для атрибута ServiceKnownType.

 [ServiceContract]
public interface ITestService {
    [OperationContract]
    [ServiceKnownType(typeof(MyComplexType))]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
    object Operation();
}