Search code examples
javascriptc#.netodatadatajs

OData Uri in batch returns 404, while if i go to the url provided, it works. Why?


I am using an ODataController to get my results for my queries. The Controller is defind as so:

public class RunController : ODataController
{
    [EnableQuery(MaxNodeCount = 1000)]
    public IHttpActionResult Get() {
        ...
    }
}

If i go directly to the controller it works. My routes are set up so that i would go to this URL:

http://localhost:58704/odata/Run

Route configuration looks like the following:

config.MapODataServiceRoute(
   routeName: "defaultOdata",
   routePrefix: "odata",
   model: GetModel(),
   batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));

Where the GetModel() looks like this:

public static Microsoft.OData.Edm.IEdmModel GetModel()
{
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<RunController.RunModel>("Run");
    return builder.GetEdmModel();
}

As you can see I have enabled a defaultOdataBatchHandler. The

http://localhost:58704/odata/$batch

Works without a hitch. Next step is to create the batch statement, which is done by datajs and looks like the following:

return OData.request({
    requestUri: "http://localhost:58704/odata/$batch",
    method: "POST",
    data: {
        __batchRequests: [
             {requestUri: "Run", method: "GET" }
        ]
    }
}, function (data, response) {
    console.log(data.__batchResponses);
}, undefined, OData.batchHandler);

The batch query gets what it needs, and returns a HTTP 200. Which is awesome. The query inside which translates to http://localhost:58704/odata/Run, returns a HTTP 404. And i cannot for the life of me understand why.

The line that says console.log(data.__batchResponses) returns 1 object that has a message property saying; "HTTP request failed", and in the response the body says:

"{"message":"No HTTP resource was found that matches the request URI 'http://localhost:58704/odata/Run'.","messageDetail":"No type was found that matches the controller named 'odata'."}"

If i use the url that is displayed in the error message, it works without a hitch. Could it be that the method: "GET" in the batch request is not working properly?


Solution

  • Based on classes and methods you've used in your ASP.NET Web API OData application,I think you're using OData V4. But your client (dataJS) does not support OData V4. You can use apache odatajs which supports OData V4 with follwing code:

    window.odatajs.oData.request({
                requestUri: "/odata/$batch",
                method: "POST",
                data: {
                    __batchRequests: [
                         { requestUri: "Products", method: "GET" }
                    ]
                }
            }, function (data, response) {
                console.log(data.__batchResponses[0].data.value);
            }, undefined, window.odatajs.oData.batch.batchHandler);
    

    There won't be any problem, API of both libraries are the same.

    Full sample which contains both server side (ASP.NET Web API OData V4) and client side (apache odatajs) can be downloaded here

    https://github.com/ymoradi/samples/tree/master/NetFX/ASP.NET/ASP.NET%20Web%20API/OData/apache%20odatajs%20v4%20sample%20code

    These are differences between two requests:

    odatajs request headers(successful one):
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    Accept: application/json;q=0.9, */*;q=0.1
    
    datajs request headers(failed one):
    MaxDataServiceVersion: 3.0
    DataServiceVersion: 1.0
    Accept: application/atomsvc+xml;q=0.8, application/json;odata=fullmetadata;q=0.7, application/json;q=0.5, */*;q=0.1