WCF REST 错误处理 - 输入不正确
本文关键字:输入 不正确 处理 REST 错误 WCF | 更新日期: 2023-09-27 18:35:11
摘要:
在 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
使用IErrorHandler
接口扩展服务。
这将允许您为任何异常提供适当的故障。这篇文章展示了如何将你自己的错误处理程序连接到你的服务行为。
我个人使用单个类来实现所有必要的元素,如下所示:
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>