Search code examples
odataasp.net-web-api2odata-v4

Web API 2 Odata V4 PATCH return 404


I have this controller :

using System.Web.Http;
using System.Web.OData;

public class InvRecipientAutoInvoiceController : ODataController
    {
        // GET: odata/InvRecipientAutoInvoice
        [EnableQuery]
        public IQueryable<Inv_RecipientAutoInvoice> GetInvRecipientAutoInvoice()
        {
            return db.Inv_RecipientAutoInvoice.Where(a=>a.CompanyNumber == CompanyNumber);
        }

    [AcceptVerbs("PATCH", "MERGE")]   
    public IHttpActionResult Patch([FromODataUri] int RecipientNumber , [FromODataUri] int RecipientType, Delta<Inv_RecipientAutoInvoice> patch)
        {
            // XXXX Some Update Code
        }
    }

The GET works and I get result and can even sort them. but when I do a PATCH request, I get 404 error , the PATCH request :

Request URL: http://localhost:61240/odata/InvRecipientAutoInvoice(RecipientNumber%3D443%2CRecipientType%3D400)

   Request Method: PATCH
  • Response Body :

{ "error":{ "code":"","message":"No HTTP resource was found that matches the request URI 'http://localhost:61240/odata/InvRecipientAutoInvoice(RecipientNumber=443,RecipientType=400)'.","innererror":{ "message":"No action was found on the controller 'InvRecipientAutoInvoice' that matches the request.","type":"","stacktrace":"" } } }

  • Request body :
{"InvoiceLine1Description":"32132"}

I am using it in an ASP.net web project (not MVC),

the register is :

config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: builder.GetEdmModel());

what am i missing?


Solution

  • @yaniv

    It seems that you want to use the built-in routing conventions to patch the entity with composite keys. However, the built-in routing conventions doesn't support the composite keys.

    You can either custom your own routing conventions ( see here ) or just use the attribute routing.

    Attribute routing is simple and easy to use. You only need to put an ODataRouteAttribute on your Patch action, then it should work.

    [AcceptVerbs("PATCH", "MERGE")]
    [ODateRoute("InvRecipientAutoInvoice(RecipientNumber={RecipientNumber},RecipientType={RecipientType})"]
    public IHttpActionResult Patch([FromODataUri] int RecipientNumber , [FromODataUri] int RecipientType, Delta<Inv_RecipientAutoInvoice> patch)
    {
         // XXXX Some Update Code
    }
    

    Thanks.