加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – WCF REST错误处理 – 输入错误

发布时间:2020-12-15 21:34:52 所属栏目:百科 来源:网络整理
导读:摘要: 在WCF REST服务中,如何使用自己的自定义故障响应处理不正确的输入参数? 详情: 我在WCF REST服务中有以下接口方法: [OperationContract][WebGet(UriTemplate = "getitem?id={itemId}",ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessa
摘要:

在WCF REST服务中,如何使用自己的自定义故障响应处理不正确的输入参数?

详情:

我在WCF REST服务中有以下接口方法:

[OperationContract]
[WebGet(UriTemplate = "getitem?id={itemId}",ResponseFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.Bare)]
[FaultContract(typeof(DataModel.Fault))]
DataModel.Item GetItem(int itemId);

在我的GetItem方法实现中,我捕获任何错误条件(即项目不存在)并创建WebFaultException.这没有任何问题.

但是,假设调用客户端调用以下url:

http://myserver.com/itemservice/getitem?id=abc

即,不能按照GetItem方法的要求将id的输入值强制转换为int

这个调用正确地失败,因为给定的id值不能转换为int,但是这个失败发生在我的任何代码执行之前,因此我不能按照分配给接口方法的FaultContract返回我的DataModel.Fault对象.

所以问题是,我如何挂钩高级错误处理程序来捕获此类型的错误,然后返回我自己的错误结构而不是WCF生成的HTML错误:

Request Error
The server encountered an error processing the request. See server logs for more details.

作为同一问题的延续,如果客户端调用以下内容,我也希望能够做同样的事情:

http://myserver.com/itemservice/gettitem?id=abc

注意URI中的拼写错误,gettitem(两个t)而不是getitem

解决方法

使用IErrorHandler接口扩展您的服务.

这将允许您为任何异常提供适当的错误.
This post显示了如何将自己的错误处理程序连接到服务行为.

我个人使用单个类来实现所有必需的元素,如下所示:

public class ErrorSavingServiceBahavior : BehaviorExtensionElement,IServiceBehavior,IErrorHandler
{
    private string m_sHostName;

    public void AddBindingParameters(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase,System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        this.m_sHostName = serviceHostBase.Description.Name;
        foreach (ChannelDispatcher chanDisp in serviceHostBase.ChannelDispatchers)
        {
            if (!chanDisp.ErrorHandlers.Contains(this))
            {
                chanDisp.ErrorHandlers.Add(this);
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase)
    {
    }

    public bool HandleError(Exception error)
    {
        //my custom code
    }

    public void ProvideFault(Exception error,System.ServiceModel.Channels.MessageVersion version,ref System.ServiceModel.Channels.Message fault)
    {
        //my custom code
    }

    public override Type BehaviorType
    {
        get { return this.GetType(); }
    }

    protected override object CreateBehavior()
    {
        return this;
    }
}

和web.config我扩展:

<behaviors>
  <serviceBehaviors>
    <behavior name="BehaviorName">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
      <saveExceptions />
    </behavior>
  </serviceBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add
      name="saveExceptions"
      type="Namespace.Class,DLLName,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"
    />
  </behaviorExtensions>
</extensions>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读