2011-12-19 52 views
3

我在C#典型的WCF REST服务,接受JSON输入,并返回一个JSON输出:WCF REST服务:WebInvoke用JSON和多态性不能正常工作

[ServiceContract] 
public class WCFService 
{ 
    [WebInvoke(Method = "POST", UriTemplate = "register", ResponseFormat = WebMessageFormat.Json)] 
    public BasicResponse RegisterNewUser(UserDTO newUser) 
    { 
     return new BasicResponse() 
     { status = "ERR_USER_NAME" }; 
    } 
} 

public class BasicResponse 
{ 
    public string status { get; set; } 
} 

public class UserDTO 
{ 
    public string username { get; set; } 
    public string authCode { get; set; } 
} 

可正常工作,但我想在正常执行和出错的情况下返回不同的对象。我创建了一个基础响应类和几个继承者。现在WCF的JSON序列崩溃并产生“400错误的请求”:

[ServiceContract] 
public class WCFService 
{ 
    [WebInvoke(Method = "POST", UriTemplate = "register", 
     ResponseFormat = WebMessageFormat.Json)] 
    public BasicResponse RegisterNewUser(UserDTO newUser) 
    { 
     return new ErrorResponse() 
     { 
      status = "ERR_USER_NAME", 
      errorMsg = "Invalid user name." 
     }; 
    } 
} 

public class BasicResponse 
{ 
    public string status { get; set; } 
} 

public class ErrorResponse : BasicResponse 
{ 
    public string errorMsg { get; set; } 
} 

public class UserDTO 
{ 
    public string username { get; set; } 
    public string authCode { get; set; } 
} 

我想没有任何成功应用[KnownType(typeof(ErrorResponse))][ServiceKnownType(typeof(ErrorResponse))]属性。看起来像DataContractJsonSerializer中的一个bug说明它支持多态。

我的WCF REST服务使用WebServiceHostFactory:

<%@ ServiceHost Language="C#" Debug="true" 
    Service="WCFService" 
    CodeBehind="CryptoCharService.svc.cs" 
    Factory="System.ServiceModel.Activation.WebServiceHostFactory" %> 

在我的web.config我有标准的HTTP端点:

<system.serviceModel> 
    <standardEndpoints> 
    <webHttpEndpoint> 
     <standardEndpoint helpEnabled="true" defaultOutgoingResponseFormat="Json" /> 
    </webHttpEndpoint> 
    </standardEndpoints> 
</system.serviceModel> 

你觉得这是可以解决的?我知道一个解决方法(手动返回字符串和序列化输出),但为什么这不起作用?

回答

1

我找到了一种方法,以部分克服了上述问题。当我需要返回一个正常值(例如BasicResponse)时,我只是返回它(我的服务返回BasicResponse对象)。当我需要返回一个错误响应,我回它作为WebFaultException这也是序列化为JSON和发送为WCF服务HTTP响应:

throw new WebFaultException<ErrorResponse>(
    new ErrorResponse() { errorMsg = "Error occured!" }, 
    HttpStatusCode.NotFound); 

现在我可以送预期的结果作为普通方法返回值和通过此WebFaultException发生错误时的任何异常结果。

0

这应该正常工作:

[DataContract] 
[KnownType(typeof(ErrorResponse)] 
public class BasicResponse 
{ 
    [DataMember] 
    public string status { get; set; } 
} 

[DataContract] 
public class ErrorResponse : BasicResponse 
{ 
    [DataMember] 
    public string errorMsg { get; set; } 
} 
+1

感谢这些建议。我知道通过WCF中的概念,我应该使用[DataContract]和[DataMember],但经过数小时的实验后,我发现DataContractJsonSerializer完全忽略了这些属性,因此我将它们从代码中移除了。你的代码没有帮助。串行器仍然崩溃,结果仍然是“400错误请求”。你知道我怎么看到序列化器抛出的异常? – 2011-12-19 22:35:04

1

ServiceKnownTypeAttribute适用于我。试试这个:

[ServiceKnownType(typeof(ErrorResponse))] 
public BasicResponse RegisterNewUser(UserDTO newUser) 
{ 
    return new ErrorResponse() 
    { 
     status = "ERR_USER_NAME", 
     errorMsg = "Invalid user name." 
    }; 
}