我有一个自定义WCF服务主机(webServicehost2
)和Factory正在执行一些依赖注入(实现自定义IInstanceProvider
)以及一些自定义身份验证(强制自定义RequestInterceptor
)
我遇到一个非常小的问题,当我导航到一个不存在的REST资源时。 例如
http://localhost/restservice.svc/
http://localhost/restservice.svc/blah/
我得到404 Error
,确定无疑。
我想知道的是,无论如何我可以捕获返回的Http错误并将其格式化得更好。
答案 0 :(得分:3)
我不确定是否有更简单的方法,但我在这里进行了一些快速原型设计,并发现实现此目的的一种方法是添加一个自定义IDispatchMessageInspector实现,该实现查看服务的响应消息并替换内容使用您自己的自定义HTML页面。
它基本上是这样的:
我的样本成功完成了这个,但它很难看;在发布之前我需要稍微清理一下。
答案 1 :(得分:1)
以下是其他任何尝试此操作的代码snipets
首先是IDispatchMessageInspector
public class CustomResponseFormatterMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
var prop = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
if (prop.StatusCode == HttpStatusCode.NotFound)
{
ErrorResponse(ref reply);
}
}
private void ErrorResponse(ref Message original)
{
const string ERROR_HTML = @"<html><HEAD><TITLE>Request Error</TITLE></HEAD><BODY> <H1>My Error processing request {1}</H1><P>{0}</P></BODY></html>";
XElement response = XElement.Load(new StringReader(string.Format(ERROR_HTML, "A Resource does not exsist at this location.", HttpStatusCode.NotFound)));
Message reply = Message.CreateMessage(original.Version, null, response);
reply.Headers.CopyHeadersFrom(original);
reply.Properties.CopyProperties(original.Properties);
original = reply;
}
}
然后将此注入我添加的IServiceBehaviour
ed.DispatchRuntime.MessageInspectors.Add(new CustomResponseFormatterMessageInspector());
此处可能还有其他与我的实施相关的代码,但这就是我添加的内容。
public class DependencyInjectionServiceBehavior : IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
var cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider =
new DependencyInjectionInstanceProvider(serviceDescription.ServiceType);
ed.DispatchRuntime.MessageInspectors.Add(new CustomResponseFormatterMessageInspector());
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}