在WCF休息服务处理404 [英] Handling 404 in WCF Rest Service

查看:133
本文介绍了在WCF休息服务处理404的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在IIS 7.5上有一个wcf rest服务。当有人访问不存在的端点的一部分(即 http://localhost/rest.svc/DOESNOTEXIST http:// localhost / EXISTS ),他们会显示一个通用的WCF灰色和蓝色的错误页面,其状态码但是,我想返回以下内容:

 < service-response> 
< error>请求的url不存在< / error>
< / service-response>

我尝试在IIS中配置自定义错误,但只有在其余部分之外请求页面时才可以使用服务(即 http:// localhost / DOESNOTEXIST )。



有没有人知道如何做?



修改
在下面的答案之后,我能够弄清楚我需要创建一个实现BehaviorExtensionElement的WebHttpExceptionBehaviorElement类。

  public class WebHttpExceptionBehaviorElement:BehaviorExtensionElement 
{
///
///获取类型行为附加到端点
///
public override Type BehaviorType
{
get
{
return typeof(WebHttpExceptionBehavior);
}
}

///
///创建自定义行为
///
保护覆盖对象CreateBehavior()
{
return new WebHttpExceptionBehavior();
}
}

然后我可以在我的网页上引用它。配置文件通过:

 < extensions> 
< behaviorExtensions>
< add name =customErrortype =Service.WebHttpExceptionBehaviorElement,Service/>
< / behaviorExtensions>
< / extensions>

然后添加

 < customError /> 

到我的默认端点行为。



谢谢,



Jeffrey Kevin Pry

解决方案

首先,创建一个自定义WebHttpBehavior的子类行为 - 这里你将删除默认的未处理的调度操作处理程序,并附加你自己的:

  public class WebHttpBehaviorEx:WebHttpBehavior 
{
public override void ApplyDispatchBehavior(ServiceEndpoint endpoint,EndpointDispatcher endpointDispatcher)
{
base.ApplyDispatchBehavior(endpoint,endpointDispatcher);

endpointDispatcher.DispatchRuntime.Operations.Remove(endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation);
endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = new DispatchOperation(endpointDispatcher.DispatchRuntime,*,*,*);
endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.DeserializeRequest = false;
endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.SerializeReply = false;
endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Invoker = new UnknownOperationInvoker();

}
}

然后。使您的未知操作处理程序。该类将处理未知操作请求并生成响应的消息。我已经展示了如何创建纯文本消息。修改它的目的应该是相当简单的:

 内部类UnknownOperationInvoker:IOperationInvoker 
{
public object [] AllocateInputs()
{
return new object [1];
}


私人消息CreateTextMessage(string message)
{
消息结果= Message.CreateMessage(MessageVersion.None,null,new HelpPageGenerator.TextBodyWriter (信息));
result.Properties [WebBodyFormatMessageProperty] = new WebBodyFormatMessageProperty(WebContentFormat.Raw);
WebOperationContext.Current.OutgoingResponse.ContentType =text / html;
返回结果;
}

public object Invoke(object instance,object [] inputs,out object [] outputs)
{
//代码HERE

StringBuilder builder = new System.Text.StringBuilder();

builder.Append(...);

消息结果= CreateTextMessage(builder.ToString());

返回结果;
}

public System.IAsyncResult InvokeBegin(object instance,object [] inputs,System.AsyncCallback callback,object state)
{
throw new System.NotImplementedException );
}

public object InvokeEnd(object instance,out object [] outputs,System.IAsyncResult result)
{
throw new System.NotImplementedException();
}

public bool IsSynchronous
{
get {return true; }
}
}

此时你必须关联新的行为与您的服务。



有几种方法可以做到这一点,所以只要问你是否还不知道,我会进一步阐述。


I have a wcf rest service on IIS 7.5. When someone visits a part of the endpoint that doesn't exist (i.e. http://localhost/rest.svc/DOESNOTEXIST vs http://localhost/EXISTS) they are presented with a Generic WCF gray and blue error page with status code 404. However, I would like to return something like the following:

<service-response>
   <error>The url requested does not exist</error>
</service-response>

I tried configuring the custom errors in IIS, but they only work if requesting a page outside of the rest service (i.e. http://localhost/DOESNOTEXIST).

Does anyone know how to do this?

Edit After the answer below I was able to figure out I needed to create a WebHttpExceptionBehaviorElement class that implements BehaviorExtensionElement.

 public class WebHttpExceptionBehaviorElement : BehaviorExtensionElement
 {
    ///  
    /// Get the type of behavior to attach to the endpoint  
    ///  
    public override Type BehaviorType
    {
        get
        {
            return typeof(WebHttpExceptionBehavior);
        }
    }

    ///  
    /// Create the custom behavior  
    ///  
    protected override object CreateBehavior()
    {
        return new WebHttpExceptionBehavior();
    }  
 }

I was then able to reference it in my web.config file via:

<extensions>
  <behaviorExtensions>
    <add name="customError" type="Service.WebHttpExceptionBehaviorElement, Service"/>
  </behaviorExtensions>
</extensions>

And then adding

<customError /> 

to my default endpoint behaviors.

Thanks,

Jeffrey Kevin Pry

解决方案

First, create a custom behavior which subclasses WebHttpBehavior - here you will remove the default Unhandled Dispatch Operation handler, and attach your own:

public class WebHttpBehaviorEx : WebHttpBehavior
{
    public override void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        base.ApplyDispatchBehavior(endpoint, endpointDispatcher);

        endpointDispatcher.DispatchRuntime.Operations.Remove(endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation);
        endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = new DispatchOperation(endpointDispatcher.DispatchRuntime, "*", "*", "*");
        endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.DeserializeRequest = false;
        endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.SerializeReply = false;
        endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Invoker = new UnknownOperationInvoker();

    }
}

Then. make your unknown operation handler. This class will handle the unknown operation request and generate a "Message" which is the response. I've shown how to create a plain text message. Modifying it for your purposes should be fairly straight-forward:

internal class UnknownOperationInvoker : IOperationInvoker
{
    public object[] AllocateInputs()
    {
        return new object[1];
    }


    private Message CreateTextMessage(string message)
    {
        Message result = Message.CreateMessage(MessageVersion.None, null, new HelpPageGenerator.TextBodyWriter(message));
        result.Properties["WebBodyFormatMessageProperty"] = new WebBodyFormatMessageProperty(WebContentFormat.Raw);
        WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
        return result;
    }

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        // Code HERE

                StringBuilder builder = new System.Text.StringBuilder();

                builder.Append("...");

                Message result = CreateTextMessage(builder.ToString());

                return result;
    }

    public System.IAsyncResult InvokeBegin(object instance, object[] inputs, System.AsyncCallback callback, object state)
    {
        throw new System.NotImplementedException();
    }

    public object InvokeEnd(object instance, out object[] outputs, System.IAsyncResult result)
    {
        throw new System.NotImplementedException();
    }

    public bool IsSynchronous
    {
        get { return true; }
    }
}

At this point you have to associate the new behavior with your service.

There are several ways to do that, so just ask if you don't already know, and i'll happily elaborate further.

这篇关于在WCF休息服务处理404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆