使用以SelfHost方式寄宿WebAPI是, 如果处理不存在的URL,   怎样能返回自己的错误消息, 而不是框架自己的消息。不存在的URL有三种情况:
 1、controller存在,action不存在。
 2、controller不存在,但URL能被Routes匹配。
 3、URL不能被Routes匹配。 1和2分别可以通过 ApiControllerActionSelector 、DefaultHttpControllerSelector 来实现。  第三种情况就不清楚怎么处理了。谢谢

解决方案 »

  1.   

    是否可以通过ExceptionFilterAttribute  来捕获不匹配?没试验过
      

  2.   

     
    ExceptionFilterAttribute  太晚了, 是捕捉action内部的错误, 没办法实现上面的功能。
      

  3.   

    那要不你就重写DefaultHttpControllerSelector ,不能匹配也是这个东西决定的
    http://blog.csdn.net/starfd/article/details/41728655
      

  4.   


    我现在是想提供一系列API,  具体什么客户端调用现在是不考虑的。   我现在只想保证我的API是按约定的标准来发送数据的。
      

  5.   

    DefaultHttpControllerSelector  也是匹配成功后才只能,  情况2就是用做个解决的。    但是匹配不成功就没办法了。        config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",  
                    defaults: new { id = RouteParameter.Optional }
                );
    注册这个路由后, 访问http://127.0.0.1:8280/api/asdasd ,  是能到DefaultHttpControllerSelector中的SelectController方法的,在这里能判断到asdasdController 是否存在,但是如果访问的是 http://127.0.0.1:8280/api2/asdasd   这种不复合规则的URL就不会到SelectController方法中。 因为没有匹配成功,  就不会创建Controller 。我尝试要匹配所有的URL,把不符合规则的跳转到指定的Controller中, 但是不知道该怎么写MapHttpRoute,因为写多了就容易乱匹配。
      

  6.   

    Url不匹配的话那不就是404了吗?
    这个应该是要重写route匹配那一块了
      

  7.   


    对,就是404了,  我就是要拦着框架自己的404的消息。   返回我自己的消息。 现在不清楚怎么重写route那块, 通过重写IHttpRouteConstraint好像不行。或者有没有办法拦截框架的消息
    throw Error.Argument("name", SRResources.RouteCollection_NameNotFound, new object[]
    {
    name
    });框架自己的消息基本上都是 throw Error.Argument 或者  throw new HttpResponseException
     
      

  8.   

    http://www.cnblogs.com/ldp615/archive/2011/12/05/asp-net-mvc-elegant-route.html
    研究下这个去吧,应该就是重写Route的部分代码,这个可能需要去下载MVC的源代码了,还要与你实际的MVC版本对应
      

  9.   

    不灵活的笨办法有一个现成的:
    在web.config里面写好可能出现的各种{controller}/{id}
    在begin_request 里判断url是否匹配{controller}/{id},不匹配就丢一个返回值。
      

  10.   

    先自定义一个继承于DelegatingHandler的消息处理器如下:namespace WebNMS.Extensions
    {
        using System.Net;
        using System.Net.Http;
        using System.Threading;
        using System.Threading.Tasks;    /// <summary>
        /// 自定义消息处理器,用HttpConfiguration.MessageHandlers.Add(obj)注册。
        /// </summary>
        public class WebNMSMessageHandler : DelegatingHandler
        {
            protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                // 通过base.SendAsync()将消息传递给管道的下一个节点。
                return base.SendAsync(request, cancellationToken).ContinueWith(
                    (t) =>
                    {
                        HttpResponseMessage response = t.Result;
                        // 在此,可以过滤你想要的任何错误代码。
                        if (response.StatusCode != HttpStatusCode.OK)
                        {
                            // 就丢弃应答中所有错误描述信息。
                            response.Content = null;
                        }
                        return response;
                        
                    }, cancellationToken);
            }
        }
    }
    然后在Main函数里,把上面的类型的实例添加到全局configuration对象:config.MessageHandlers.Add(new WebNMSMessageHandler());
    就是这么简单。原理就是在消息处理管道里添加自定以消息处理器,这样可以捕获输入的request和输出的resopnse。