WCF REST服务:带有JSON和多态性的WebInvoke不能正常工作

本文关键字:常工作 不能 工作 WebInvoke 服务 REST 带有 JSON 多态性 WCF | 更新日期: 2023-09-27 18:18:32

我有一个典型的c# WCF REST服务,它接受JSON输入并返回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))]属性,但没有成功。似乎是一个bug在DataContractJsonSerializer声明它支持多态性。

我的WCF REST服务使用WebServiceHostFactory:
<%@ ServiceHost Language="C#" Debug="true" 
    Service="WCFService" 
    CodeBehind="CryptoCharService.svc.cs"
    Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

In my Web。我有标准的HTTP端点:

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

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

WCF REST服务:带有JSON和多态性的WebInvoke不能正常工作

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

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

现在我可以发送预期的结果作为一个正常的方法返回值和任何异常的结果,在错误的情况下,通过这个WebFaultException。

ServiceKnownTypeAttribute适合我。试试这个:

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

应该可以正常工作:

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