我可以在 Web api 中使用非 Rest 风格的方法吗?

Can I have non Rest styled Methods in web api?

我的问题具体是我是否可以支持这样的东西

public class SomeTestController : ApiController
    {


        [System.Web.Http.AcceptVerbs("GET")]
        public SomeInfo GetSomeBlah(int a, int b)
        {
            return new SomeInfo 
            {
                Name = string.Format("GetSomeBlah - {0}", a),
                CompanyID = b.ToString()

            };
        }

        [System.Web.Http.AcceptVerbs("GET")]
        public SomeInfo GetSomeBlah1(int a, int b)
        {
            return new SomeInfo 
            {
                Name = string.Format("GetSomeBlah1 - {0}", a),
                CompanyID = b.ToString()

            };
        }

    }

我尝试添加以下路由

config.Routes.MapHttpRoute(
        name: "DefaultApi4",
        routeTemplate: "api/{controller}/{action}",
        defaults: new {action = RouteParameter.Optional}
        );

编辑:2015 年 4 月 7 日

我忘了说它也应该适用于 rest 风格的方法。

如果您删除默认路由,这将起作用。我还指出了参数的来源。

指定输入来自URL:

public SomeInfo GetSomeBlah([FromUri] int a, [FromUri] int b)

评论或删除:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

测试URL:

http://localhost:64719/api/Values/GetSomeBlah?a=1&b=2

回复:

<ValuesController.SomeInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SampleMVC.Controllers"> <CompanyID>2</CompanyID><Name>GetSomeBlah - 1</Name> </ValuesController.SomeInfo>

不确定您为什么要尝试这样做,听起来您误解了路由的工作原理 - 您是否 seen these tutorials 了解路由以及如何 ASP.net 映射路由?

从下面的第 3b 点开始,这意味着如果您更有意义地命名输入变量,框架将能够映射来自路由的名称和类型,以决定选择哪种方法,即 getSomeBlah 或 GetSomeBlack1

为他人总结,

1). Create a list of all actions on the controller that match the HTTP request method.

2). If the route dictionary has an "action" entry, remove actions whose name does not match this value.

3). Try to match action parameters to the URI, as follows:

a). For each action, get a list of the parameters that are a simple type, where the binding gets the parameter from the URI. Exclude optional parameters.

b). From this list, try to find a match for each parameter name, either in the route dictionary or in the URI query string. Matches are case insensitive and do not depend on the parameter order.

c). Select an action where every parameter in the list has a match in the URI.

d). If more that one action meets these criteria, pick the one with the most parameter matches.

4). Ignore actions with the [NonAction] attribute.

这样配置:

        config.Routes.MapHttpRoute("DefaultApi2", 
          "apiws/{controller}/{action}/{id}", 
           new { id = RouteParameter.Optional });

        config.Routes.MapHttpRoute("DefaultApi", 
         "apiws/{controller}/{id}", 
         new { id = RouteParameter.Optional });

这适用于休息风格和非休息风格的 api。 请注意,两个语句的顺序很重要。

我设法让它与以下代码一起工作

    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

和属性路由。

    [RoutePrefix("api/someother")]
    public class SomeOtherController : ApiController
    {
        // GET: api/SomeOther
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET: api/SomeOther/5
        public string Get(int id)
        {
            return "value";
        }

        // POST: api/SomeOther
        public void Post([FromBody]string value)
        {
        }

        // PUT: api/SomeOther/5
        public void Put(int id, [FromBody]string value)
        {
        }

        [System.Web.Http.HttpGet()]
        [System.Web.Http.Route("Findsomething2")]
        public CompanyInfo Findsomething2(int id, int b)
        {
            return new CompanyInfo
            {
                CompanyID = b.ToString(),
                Name = id.ToString() + " 2"

            };
        }

        // DELETE: api/SomeOther/5
        public void Delete(int id)
        {
        }
    }