由于试图从我们所有的 Web 服务中删除面向方面的代码,我遇到了一个奇怪的问题。
有一个 IParameterInspector 进行验证并抛出一个在返回响应的 IErrorHandler 中捕获的 FaultException。
ResponseBase 看起来像这样:
[DataContract(Namespace = Namespaces.Data)]
public class ResponseBase
{
public ResponseBase()
{
this.Build = BuildHelper.GetBuild();
}
[DataMember(Name = CommonParameterNames.RequestId, Order = 0)]
public string RequestId { get; set; }
[DataMember(Name = CommonParameterNames.Status, Order = 1)]
public string Status { get; set; }
[DataMember(Name = CommonParameterNames.Errors, Order = 2, EmitDefaultValue = false)]
public Error[] Errors { get; set; }
[DataMember(Name = CommonParameterNames.Build, Order = 3, EmitDefaultValue = false)]
public Build Build { get; set; }
}
这是由 Web 服务方法创建的所有响应的基类。
当它从服务方法返回而没有发生错误或验证错误时,消息在正文中包含一个包装元素,该元素具有一个名为“response”的命名空间,就在方法名称本身的开始标记之后:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body>
<BulkUploadImageBase64Response xmlns="http://www.mydomain.com/webapi/">
<response xmlns:a="http://www.mydomain.com/webapi/data/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:request_id>
但是,如果我尝试处理 IErrorHandler 中的故障,使用 Message.CreateMessage() 方法,从 FaultException 传递 ResponseBase 对象,结果看起来会有所不同:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body>
<BulkUploadImageResponse xmlns="http://www.mydomain.com/webapi/data/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<request_id>e505d0d3-fc5d-474f-8ec7-5c7521c8a869</request_id>
<status>DataValidationError</status>
从错误处理程序返回的 Message 似乎以不同的方式序列化。由于某种原因,缺少“响应”包装元素。
这是错误处理程序的实现(摘录):
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
if (error is FaultException<ResponseBase>)
{
var fe = error as FaultException<ResponseBase>;
fault = Message.CreateMessage(version, null, fe.Detail);
}
我已经尝试过不同的事情:将 BodyReader 与 DataContractSerializer 一起使用,将 MessageContract 属性添加到 ResponseBase 类等等,但我不能让它看起来像框架隐式生成的响应消息。
非常感谢任何帮助,非常感谢!