【问题标题】:Web API routing actionsWeb API 路由操作
【发布时间】:2014-02-15 15:17:16
【问题描述】:

目标是允许这四个端点:

POST    v1/invoices<br/>
POST    v1/invoices/12345<br/>
POST    v1/invoices/12345/attachment<br/>
POST    v1/invoices/12345/image

路由条目:

routes.MapHttpRoute(
        name: "InvoiceAttachments",
        routeTemplate: "v1/invoices/{id}/attachments",
        defaults: new { controller = "invoices", action = "PostAttachment" }
    );

routes.MapHttpRoute(
        name: "InvoiceImages",
        routeTemplate: "v1/invoices/{id}/images",
        defaults: new { controller = "invoices", action = "PostImage" }
    );

这是我在控制器中的四个函数定义:

[HttpPost]
[ActionName("PostAttachment")]
public HttpResponseMessage PostAttachment(int id)

[HttpPost]
[ActionName("PostImage")]
public HttpResponseMessage PostImage(int id)

[HttpPost]
public HttpResponseMessage Post(int id)    

[HttpPost]
public HttpResponseMessage Post()

然而,当我使用第一个 URI 发布发票时,被识别的路由是附件路由。如何在 ID 变量之后有不同部分的端点?

【问题讨论】:

    标签: c# asp.net-web-api asp.net-web-api-routing


    【解决方案1】:

    知道了!

    路线:

    routes.MapHttpRoute(
            name: "InvoiceStuff",
            routeTemplate: "v1/invoices/{id}/{*action}",
            defaults: new { controller = "invoices", action = "" }
        );
    

    函数定义:

    [HttpPost]
    [ActionName("Attachments")]
    public HttpResponseMessage Attachments([FromUri]int id)
    
    [HttpPost]
    [ActionName("Images")]
    public HttpResponseMessage Images([FromUri]int id)
    
    [HttpPost]
    public HttpResponseMessage Post()
    
    [HttpPost]
    [ActionName("")]
    public HttpResponseMessage Post([FromUri]int id)
    

    完美运行。请注意,由于带有通配符的 webAPI 路由存在缺陷,我在路由中指定了默认操作“”。如果我没有做默认设置,就会抛出空引用异常。有关该缺陷的更多信息,请参见:http://aspnetwebstack.codeplex.com/workitem/718 - 计划在 ASP.NET v5 中修复。

    感谢您的帮助!

    【讨论】:

      【解决方案2】:

      我认为您必须定义另一个路由,因为第一个 URI 不应该与 InvoiceAttachments 路由匹配,因为它末尾没有“/attachments”

      【讨论】:

        【解决方案3】:

        尝试使用单一路线

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

        然后像这样装饰函数

        [HttpPost]
        [ActionName("DefaultAction")]
        public HttpResponseMessage Post()
        
        
        [HttpPost]
        public HttpResponseMessage PostImage(int id)
        

        【讨论】:

        • 当我执行 /invoices/12345 时,它不起作用,它进入默认操作,没有传入 id 参数。:/
        • @NiX - 你试过改变上面的 DefaultAction 来接受 int id 参数吗? Post(int id) - 否则您将永远无法获得传入的 id...
        • 是的,我刚刚意识到我忘记了所需的端点之一:POST /v1/invoices 所以我需要一个 post() 和一个 post(int id)
        【解决方案4】:

        您是否尝试过使用约束而不是默认值?

        routes.MapHttpRoute(
                name: "InvoiceAttachments",
                routeTemplate: "v1/invoices/{id}/attachments",
                defaults: new { controller = "invoices" },
                constraints: new { action = "PostAttachment" } 
            );
        
        routes.MapHttpRoute(
                name: "InvoiceImages",
                routeTemplate: "v1/invoices/{id}/images",
                defaults: new { controller = "invoices" },
                constraints: new { action = "PostImage" } 
            );
        
        routes.MapHttpRoute(
                name: "Default",
                routeTemplate: "v1/invoices/{id}",
                defaults: new { controller = "invoices" }
            );
        

        更新:

        您可以通过将操作设置为 url 部分来破解它:

        routes.MapHttpRoute(
                name: "InvoiceAttachments",
                routeTemplate: "v1/invoices/{id}/{action}",
                defaults: new { controller = "invoices" },
                constraints: new {action = "attachments|images"}
            );
        
        routes.MapHttpRoute(
                    name: "default",
                    routeTemplate: "v1/invoices/{id}",
                    defaults: new { controller = "invoices", id = RouteParameter.Optional },
                    constraints: new {action = "attachments|images"}
                );
        

        和控制器方法:

        [HttpPost]
        [ActionName("attachments")]
        public HttpResponseMessage PostAttachment(int id)
        
        [HttpPost]
        [ActionName("images")]
        public HttpResponseMessage PostImage(int id)
        
        public HttpResponseMessage Post(int id)
        
        public HttpResponseMessage Post()
        

        【讨论】:

        • 尝试过并得到此异常:“找到与请求匹配的多个操作:\r\nSystem.Net.Http.HttpResponseMessage PostAttachment(Int32) on type Controllers.Api.InvoicesController\r\nSystem .Net.Http.HttpResponseMessage Post(Int32) on type Controllers.Api.InvoicesController",
        猜你喜欢
        • 2013-09-10
        • 2018-01-01
        • 2013-06-15
        • 1970-01-01
        • 2018-09-17
        • 1970-01-01
        • 2013-05-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多