我在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 Bad Request":
[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
中的一个错误,它指出它支持多态。
我的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>
你认为这是可以解决的吗?我知道一种解决方法(返回字符串并手动序列化输出),但为什么这不起作用?
答案 0 :(得分:1)
我找到了部分克服所描述问题的方法。当我需要返回一个正常值(例如BasicResponse)时,我只返回它(我的服务返回BasicResponse对象)。当我需要返回错误响应时,我将其作为WebFaultException返回,它也被序列化为JSON并作为HTTP响应发送到WCF服务:
throw new WebFaultException<ErrorResponse>(
new ErrorResponse() { errorMsg = "Error occured!" },
HttpStatusCode.NotFound);
现在我可以通过此WebFaultException将预期结果作为普通方法返回值和任何异常结果发送。
答案 1 :(得分:1)
ServiceKnownTypeAttribute适合我。试试这个:
[ServiceKnownType(typeof(ErrorResponse))]
public BasicResponse RegisterNewUser(UserDTO newUser)
{
return new ErrorResponse()
{
status = "ERR_USER_NAME",
errorMsg = "Invalid user name."
};
}
答案 2 :(得分: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; }
}