让Web API同时支持多个Get方法

来源:互联网 发布:斗鱼刷人气软件那个好 编辑:程序博客网 时间:2024/06/08 16:51

WebApi中多个Get方法请求出错的问题就不赘述了,不然你也不会来这里找答案。

思路就是要定义一个constraints去实现:
我们先分析下uri path: api/controller/x,问题就在这里的x,它有可能代表action也有可能代表id,其实我们就是要区分这个x什么情况下代表action什么情况下代表id就可以解决问题了,我是想自己定义一系统的动词,如果你的actoin的名字是以我定义的这些动词中的一个开头,那么我认为你是action,否则认为你是id。

好,思路说明白了,我们开始实现,先定义一个StartWithConstraint类

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Http.Routing;namespace GM360_REWARD_SERVICES.Common{    /// <summary>     /// 如果请求url如: api/area/controller/x x有可能是actioin或id     /// 在url中的x位置出现的是以 get put delete post开头的字符串,则当作action,否则就当作id     /// 如果action为空,则把请求方法赋给action     /// </summary>     public class StartWithConstraint : IHttpRouteConstraint    {        public string[] array { get; set; }        public bool match { get; set; }        private string _id = "id";        public StartWithConstraint(string[] startwithArray = null)        {            if (startwithArray == null) startwithArray = new string[] { "GET", "PUT", "DELETE", "POST", "EDIT", "UPDATE", "AUDIT", "DOWNLOAD" };            this.array = startwithArray;        }        public bool Match(System.Net.Http.HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)        {            if (values == null) // shouldn't ever hit this.                 return true;            if (!values.ContainsKey(parameterName) || !values.ContainsKey(_id)) // make sure the parameter is there.                 return true; var action = values[parameterName].ToString().ToLower();            if (string.IsNullOrEmpty(action)) // if the param key is empty in this case "action" add the method so it doesn't hit other methods like "GetStatus"             {                values[parameterName] = request.Method.ToString();            }            else if (string.IsNullOrEmpty(values[_id].ToString()))            {                var isidstr = true;                array.ToList().ForEach(x => { if (action.StartsWith(x.ToLower())) isidstr = false; });                if (isidstr)                {                    values[_id] = values[parameterName]; values[parameterName] = request.Method.ToString();                }            }            return true;        }    }}

然后在对应的API路由注册时,添加第四个参数constraints:

  转载原文:

GlobalConfiguration.Configuration.Routes.MapHttpRoute(     this.AreaName + "Api", "    api/" + this.AreaName + "/{controller}/{action}/{id}",     new { action = RouteParameter.Optional, id = RouteParameter.Optional,     namespaceName = new string[] { string.Format("Zephyr.Areas.{0}.Controllers",this.AreaName) } },    new { action = new StartWithConstraint() } );


  上面添加了命名空间,我自己的项目没有多个项目,所以不需要对命名空间进行处理

 

RouteTable.Routes.MapHttpRoute(                "RewardServices",                "api/{controller}/{action}/{id}",                new { action = RouteParameter.Optional, id = RouteParameter.Optional },                new { action=new StartWithConstraint() }                );

这样就实现了,Api控制器中Action的取名就要注意点就是了,不过还算是一个比较完美的解决方案。

不知道原文地址

贴上自己看到的网址:点击打开链接

原创粉丝点击