Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OData v4 Function always returns 404

Trying to move from OData v3 to OData v4. Why do I keep getting a 404 when trying to use OData Functions?

Web API Config:

ODataModelBuilder builder = new ODataConventionModelBuilder();
//etc
builder.EntitySet<LocalizableString>("LocalizableStringApi");
//etc
var getComparitiveTableFunction = builder.EntityType<LocalizableString>().Collection.Function("GetComparitiveTable");
getComparitiveTableFunction.Parameter<string>("cultureCode");
getComparitiveTableFunction.ReturnsCollection<ComparitiveLocalizableString>();
//etc
config.MapODataServiceRoute("OData_Kore_CMS", "odata/kore/cms", builder.GetEdmModel());

C# Code:

[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
[HttpGet]
//[ODataRoute("Default.GetComparitiveTable(cultureCode={cultureCode})")] // Tried this, but gets errors and I noticed the function is in the OData model anyway without this, so should be fine.
public virtual IHttpActionResult GetComparitiveTable([FromODataUri] string cultureCode)
{
    // Implementation
    return Ok(query);
}

XML Returned from $metadata:

<Schema Namespace="Default">
    <Function Name="GetComparitiveTable" IsBound="true">
        <Parameter Name="bindingParameter" Type="Collection(Kore.Localization.Domain.LocalizableString)"/>
        <Parameter Name="cultureCode" Type="Edm.String" Unicode="false"/>
        <ReturnType Type="Collection(Kore.Localization.Models.ComparitiveLocalizableString)"/>
    </Function>
    ...

As you can see, it's in the schema / OData model... yet the following query does not work:

http://localhost:30863/odata/kore/cms/LocalizableStringApi/Default.GetComparitiveTable(cultureCode='en-US')

I have also tried the following:

http://localhost:30863/odata/kore/cms/LocalizableStringApi/GetComparitiveTable(cultureCode='en-US')
http://localhost:30863/odata/kore/cms/Default.GetComparitiveTable(cultureCode='en-US')
http://localhost:30863/odata/kore/cms/GetComparitiveTable(cultureCode='en-US')

All of the above result in a 404.

So... what am I doing wrong here?

like image 604
Matt Avatar asked Aug 18 '15 03:08

Matt


4 Answers

I solve a similar problem adding a trailing slash to the requested url.

like image 111
Narciso Oceguera Avatar answered Nov 01 '22 03:11

Narciso Oceguera


I solved this by adding the following line in my web.config, under <system.webServer>:

<modules runAllManagedModulesForAllRequests="true">

This may cause performance issues though, if I remember correctly. So it's not ideal. Any better solutions are very welcome...

like image 26
Matt Avatar answered Nov 01 '22 02:11

Matt


You need a module that goes by the name of UrlRoutingModule-4.0 to be running through IIS. This solution causes all your registered HTTP modules to run on every request, not just managed requests (e.g. .aspx). This means modules will run on ever .jpg .gif .css .html .pdf etc.

So, a better solution would be to add the following in your web.config

<modules>
  <remove name="UrlRoutingModule-4.0" />
  <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>

Source: http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html

like image 3
Sebastian Zaklada Avatar answered Nov 01 '22 03:11

Sebastian Zaklada


This is a solution to prevent 404 Not Found error with OData functions / actions.

Benefits of this solution

  • Works with OData URI without slash at end (example: http://domain.org/odata/Objects/ObjectService.Action)
  • Works with OData URI with a slash at end (example: http://domain.org/odata/Objects/ObjectService.Action/)
  • Doesn't cause any performance issue.

Add theses lines in your web.config

<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0Custom" path="/odata*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

Et Voilà :)

like image 2
rdhainaut Avatar answered Nov 01 '22 02:11

rdhainaut