2011-05-26 5 views
0

Давайте предположим, что у меня есть простая служба WCF:службы WCF, Json сериализация и ошибки устанавливающих

[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.OperationResult; 
    }, 
    error: function (xhr, msg, thrown) { 
    var error = xhr; 
    } 
}); 

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

ответ

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

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

[ServiceContract] 
public interface ITestService { 
    [OperationContract] 
    [ServiceKnownType(typeof(MyComplexType))] 
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)] 
    object Operation(); 
} 
Смежные вопросы