- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我已经实现了 IErrorHandler 来处理在我的 restful WCF 服务的构造函数中抛出的授权异常。当捕获到一般异常时,我的自定义类型按预期返回,但 ContentType header 不正确。
HTTP/1.1 500 Internal Server Error
Content-Type: application/xml;
...
{"ErrorMessage":"Error!"}
然而,当错误处理程序尝试返回 401 Unauthorized http 状态代码时,消息正文将被覆盖为默认类型,但 ContentType header 是它应该的。
HTTP/1.1 401 Unauthorized
Content-Type: application/json;
...
{"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"}
显然这里有问题,但我不确定是什么。
我如何实现 IErrorHandler 以使其在 json 中返回带有正确 header 的自定义类型?
BaseDataResponseContract 对象:
[Serializable]
[DataContract( Name = "BaseDataResponseContract" )]
public class BaseDataResponseContract
{
[DataMember]
public string ErrorMessage { get; set; }
} // end
这是我要返回的对象。我的应用程序中的所有其他对象都继承自该对象。当抛出异常时,我们真正关心的是 http 状态代码和错误消息。
IErrorHandler 实现(为简洁起见未显示日志记录):
namespace WebServices.BehaviorsAndInspectors
{
public class ErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
} // end
public void ProvideFault(Exception ex, MessageVersion version, ref Message fault)
{
// Create a new instance of the object I would like to return with a default message
var baseDataResponseContract = new BaseDataResponseContract { ErrorMessage = "Error!" };
// Get the outgoing response portion of the current context
var response = WebOperationContext.Current.OutgoingResponse;
// Set the http status code
response.StatusCode = HttpStatusCode.InternalServerError;
// If the exception is a specific type change the default settings
if (ex.GetType() == typeof(UserNotFoundException))
{
baseDataResponseContract.ErrorMessage = "Invalid Username!";
response.StatusCode = HttpStatusCode.Unauthorized;
}
// Create the fault message that is returned (note the ref parameter)
fault = Message.CreateMessage(version, "", baseDataResponseContract, new DataContractJsonSerializer(typeof(BaseDataResponseContract)));
// Tell WCF to use JSON encoding rather than default XML
var webBodyFormatMessageProperty = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProperty);
// Add ContentType header that specifies we are using json
var httpResponseMessageProperty = new HttpResponseMessageProperty();
httpResponseMessageProperty.Headers[HttpResponseHeader.ContentType] = "application/json";
fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponseMessageProperty);
} // end
} // end class
} // end namespace
IServiceBehavior 实现:
namespace WebServices.BehaviorsAndInspectors
{
public class ErrorHandlerExtensionBehavior : BehaviorExtensionElement, IServiceBehavior
{
public override Type BehaviorType
{
get { return GetType(); }
}
protected override object CreateBehavior()
{
return this;
}
private IErrorHandler GetInstance()
{
return new ErrorHandler();
}
void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } // end
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
var errorHandlerInstance = GetInstance();
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(errorHandlerInstance);
}
}
void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } // end
} // end class
} // end namespace
网络配置:
<system.serviceModel>
<services>
<service name="WebServices.MyService">
<endpoint binding="webHttpBinding" contract="WebServices.IMyService" />
</service>
</services>
<extensions>
<behaviorExtensions>
<!-- This extension if for the WCF Error Handling-->
<add name="ErrorHandlerBehavior" type="WebServices.BehaviorsAndInspectors.ErrorHandlerExtensionBehavior, WebServices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<ErrorHandlerBehavior />
</behavior>
</serviceBehaviors>
</behaviors>
....
</system.serviceModel>
最后,我在使用 WebFaultException 时看到了类似的行为。我的想法是,这是一些深藏不露的 .Net 恶作剧的结果。我选择实现 IErrorHandler,这样我就可以捕获任何其他可能无法处理的异常。
引用:
https://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler(v=vs.100).aspx
其他例子:
IErrorHandler doesn't seem to be handling my errors in WCF .. any ideas?
How to make custom WCF error handler return JSON response with non-OK http code?
How do you set the Content-Type header for an HttpClient request?
最佳答案
我不太确定您的应用程序是如何实现的。根据你的描述,我建议使用visual studio调试你的ErrorHandler,看看异常是否到达你的回调。
如果是,请以您想要的方式手动构建 soap 故障或响应。
如果不是,则意味着异常发生在到达您的服务操作之前,它可能已经在 Channel 堆栈中失败,在这种情况下,一种简单的方法是添加额外的 HttpModule 来自定义或映射响应。或者您可以尝试在 channel 堆栈中自定义编码器。
关于c# - IErrorHandler 在 HTTP 状态代码为 401 Unauthorized 时返回错误的消息正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38231970/
如果我同时拥有 IParameterInspector和 IErrorHandler我可以确定附加到服务上吗IErrorHandler.HandleError()将在 IParameterInspec
我的服务方式标有PrincipalPermissionAttribute我有一个自定义 IErrorHandler附加到服务的实现。当传入的请求无权执行方法System.Security.Securi
(类似于 this 问题,但在这种情况下最终不需要) 我正在使用 IErrorHandler 实现——创建一个FaultException,以便服务的客户端在出现未处理的异常时收到“漂亮”的错误。 我
我正在尝试在wcf服务中强加自定义错误处理程序fo rest endpoin以在错误时返回未包装的字符串 public void ProvideFault(Exception erro
在尝试反序列化一个相对较大的对象图时,我看到了奇怪的行为 ~10000 行,上面有 6 列。我确定问题是在尝试将此数组从服务反序列化回客户端时出现序列化异常。它适用于少于 9000 个对象的数据集,并
我有一个 WCF 服务,我有一个绑定(bind)了 IErrorHandler 的 FaultContract,它运行良好。出于某种我不知道的原因,它在运行时停止绑定(bind)。当我在 ApplyD
我有一个 WCF 4 Rest 服务,它由一个 java 客户端和一个 c# mvc3 客户端使用。响应内容需要以json形式返回。 我希望能够以一致的方式将任何异常/故障返回给客户。我读到应该使用
我似乎无法让 IErrorHandler 接口(interface)正常工作。我的代码是 using System; using System.Collections.Generic; using S
可能是个微不足道的问题。我想实现自己的错误处理程序来记录错误并监视正在发生的事情。在这一点上,我不想向客户提供我自己的错误。我希望它是透明的——就像默认的 WCF 行为一样。我应该如何实现 Provi
一直在阅读 IErrorHandler 并想要走配置路线。因此,我阅读了以下内容以尝试实现它。 MSDN Keyvan Nayyeri blog about the type defintion Ro
我在我的 Wcf 服务项目中使用 CaSTLe windsor 3.0。我使用 Topshelf 将其托管为 Windows 服务项目。我所有的 wcf 服务配置都在 app.config 文件中。
我有这种情况:我有 WCF 服务。我通过 MyErrorHandler 和已实现的接口(interface) IErrorHandler 处理所有异常。下面是整个工作代码。 我想做什么,但不知道怎么做
一些上下文:我们有一个自定义 XSD 并使用 WSCF.blue 生成 WSDL 和 C# 代码。客户端使用 ChannelFactory并共享接口(interface),其中包括 WSCF.blue
我基本上是在实现 IErrorHandler 接口(interface)来捕获来自 WCF 服务的各种异常,并通过实现 ProvideFault 方法将其发送到客户端。 然而,我面临一个关键问题。所有
无法使用正确的 web.config 将 IErrorHandler 集成到我的项目中 我有一个成功运行的 WCF,它正在被 .net 4 中的 webclients 使用,但是当尝试将 IError
当然,我们必须避免捕获和尝试处理 AccessViolationExceptions (AVE)。但是,在我当前的情况下,异常是从 COM+ 托管组件抛出的,该组件终止了抛出异常的进程,因此可以正确清
我希望能够捕获所有未处理的异常并返回预期的 DTO 但填充了一些错误信息。例如 public class CreateFooRequest { public string Name { get
我想在 WCF 服务上安装 IErrorHandler 的实现。 我目前正在使用这段代码,它似乎没有做任何事情: logServiceHost = new ServiceHost(typeof(Log
我已经实现了 IErrorHandler 来处理在我的 restful WCF 服务的构造函数中抛出的授权异常。当捕获到一般异常时,我的自定义类型按预期返回,但 ContentType header
我的目的是检测 WCF 服务内未处理的错误,记录它们并关闭应用程序。 为此,我使用了 WCF 的 IErrorHandler。在方法 HandleError(Exception error) 中,我被
我是一名优秀的程序员,十分优秀!