分享

WebApi 路由机制剖析:你准备好了吗?(下)

 weijianian 2016-08-07


来源:懒得安分

链接:http://www.cnblogs.com/landeanfen/p/5501490.html


四、WebApi特性路由


上面说了这么多都是路由的一些全局配置。并且存在问题:


如果http请求的方法相同(比如都是post请求),并且请求的参数也相同。这个时候似乎就有点不太好办了,这种情况在实际项目中还是比较多的。比如


public class OrderController : ApiController

    {

        //订单排产

        [HttpPost]

        public void OrderProduct([FromBody]string strPostData)

        {

 

        }

 

        //订单取消

        [HttpPost]

        public void OrderCancel([FromBody]string strPostData)

        {

            

        }

 

        //订单删除

        [HttpPost]

        public void OrderDelete([FromBody]string strPostData)

        {

          

        }

    }


这个时候如果使用我们上面讲的Restful风格的路由是解决不了这个问题的。当然,有园友可能就说了,既然这样,我们在路由模板里面加上“{action}”不就搞定了么!这样确实可行。但还是那句话,不提倡。我们来看看如何使用特性路由解决这个问题。


1、启动特性路由


如果要使用特性路由,首先在WebApiConfig.cs的Register方法里面必须先启用特性路由:


public static void Register(HttpConfiguration config)

        {

            // 启用Web API特性路由

            config.MapHttpAttributeRoutes();

 

            //1.默认路由

            config.Routes.MapHttpRoute(

                name'DefaultApi',

                routeTemplate'api/{controller}/{id}',

                defaultsnew { id = RouteParameter.Optional }

            );

        }


一般情况下,当我们新建一个WebApi项目的时候,会自动在Register方法里面加上这句话。


2、最简单的特性路由


我们在OrderController这个控制器里面加这个action


[Route('Order/SaveData')]

        [HttpPost]

        public HttpResponseMessage SavaData(ORDER order)

        {

            return Request.CreateResponse();

        }


然后我们通过Web里面的Ajax调用


$(function () {

    $.ajax({

        type'post',

        url'http://localhost:21528/Order/SaveData',

        data{ ID2, NO:'aaa'},

        successfunction (data, status) {

            alert(data);

        }

    });

});



得到结果:



当然,有人可能就有疑义了,这个特性路由的作用和“{action}”的作用一样嘛,其实不然,如果这里改成 [Route(“Test/AttrRoute”)] ,然后请求的url换成http://localhost:21528/Test/AttrRoute,一样能找到对应的action。



特性路由的目的是为了解决我们公共路由模板引擎解决不了的问题。一个action定义了特性路由之后,就能通过特性路由上面的路由规则找到。


3、带参数的特性路由



特性路由的规则可以使用“{}”占位符动态传递参数,比如我们有这样一个特性路由


[Route('ordertype/{id}/order')]

        [HttpGet]

        public IHttpActionResult GetById(int id)

        {

            return Okstring>('Success' + id );

        }


在浏览器里面调用



调用成功。到此,我们就能看懂本文最开始那个看似“怪异”的路由→/api/user/1/detail这个了。


4、参数的约束和默认值


 [Route('api/order/{id:int=3}/ordertype')]

        [HttpGet]

        public IHttpActionResult GetById(int id)

        {

            return Okstring>('Success' + id );

        }


这里约束可变部分{id}的取值必须是int类型。并且默认值是3.


看看效果



不满足约束条件,则直接返回404。


5、路由前缀


在正式项目中,同一个控制器的所有的action的所有特性路由标识一个相同的前缀,这种做法并非必须,但这样能够增加url的可读性。一般的做法是在控制器上面使用特性[RoutePrefix]来标识。


[RoutePrefix('api/order')]

    public class OrderController : ApiController

    {

        [Route('')]

        [HttpGet]

        public IHttpActionResult GetAll()

        {

            return Okstring>('Success');

        }

 

        [Route('{id:int}')]

        [HttpGet]

        public IHttpActionResult GetById(int id)

        {

            return Okstring>('Success' + id );

        }

 

        [Route('postdata')]

        [HttpPost]

        public HttpResponseMessage PostData(int id)

        {

            return Request.CreateResponse();

        }

    }


那么这个这个控制器的action的时候,都需要/api/order开头,后面接上action特性路由的规则。


五、第一个Restful风格的WebApi服务



通过以上,我们就可以构造一个Restful风格的WebApi服务。


[RoutePrefix('api/AttrOrder')]

    public class OrderController : ApiController

    {

        [Route('')]

        [HttpGet]

        public IHttpActionResult GetAll()

        {

            return Okstring>('Success');

        }

 

        [Route('{id:int=3}/OrderDetailById')]

        [HttpGet]

        public IHttpActionResult GetById(int id)

        {

            return Okstring>('Success' + id );

        }

 

        [Route('{no}/OrderDetailByNo')]

        [HttpGet]

        public IHttpActionResult GetByNO(string no)

        {

            return Okstring>('Success' + no);

        }

 

        [Route('{name}/OrderDetailByName')]

        [HttpGet]

        public IHttpActionResult GetByName(string name)

        {

            return Okstring>('Success' + name);

        }

 

        [Route('postdata')]

        [HttpPost]

        public HttpResponseMessage PostData(int id)

        {

            return Request.CreateResponse();

        }

 

        [Route('Test/AttrRoute')]

        [HttpPost]

        public HttpResponseMessage SavaData(ORDER order)

        {

            return Request.CreateResponse();

        }

    }


得到结果



六、总结


整了这么久终于整完了。如果你觉得本文对你有帮助,请帮忙博主推荐,您的支持是博主最大的动力!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多