【问题标题】:WCF REST Error Handling - Incorrect InputsWCF REST 错误处理 - 输入不正确
【发布时间】:2012-05-23 15:32:36
【问题描述】:

总结:

在 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

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

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

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

请求错误 服务器在处理请求时遇到错误。有关详细信息,请参阅服务器日志。

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

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

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

【问题讨论】:

    标签: c# wcf rest


    【解决方案1】:

    使用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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      相关资源
      最近更新 更多