Вопрос

I have a working web application configured to use Web Api together with areas. I have 2 areas, Admin and Client. This means, to target a controller I have to call the url like this:

/xxxWebClient/api/1.0.0/projectid/Products

and everything works fine. This is my routeConfig:

//Route to Client
        routes.MapRoute(
           name: "Client",
           url: "Client",
           defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
           namespaces: new string[] { "xxx.Web.Areas.xxxWebClient.Controllers" }
       ).DataTokens.Add("Area", "xxxWebClient");

        //Route to Admin
        routes.MapRoute(
           name: "Admin",
           url: "Admin",
           defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
           namespaces: new string[] { "xxx.Web.Areas.xxxWebAdmin.MvcControllers" }
       ).DataTokens.Add("Area", "xxxWebAdmin");

I now want to enable odata so that it would target the same controller. The problem is that I want not only to use the Odata WebAPI features, which are available simply by adding the [Queryable] attribute to the methods (and which work great), but I have to extend my Controller to the new AsyncEntitySetController in order to retrieve and use the QueryOptions generated automatically when calling an odata url. I already have the latest nuGet packages (odata, edm and spatial), and in order to for the project to compile I had to add these assembly binding redirects to the web.config:

<dependentAssembly>
    <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-5.4.0.0" newVersion="5.4.0.0" />
  </dependentAssembly>      
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-5.4.0.0" newVersion="5.4.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-5.4.0.0" newVersion="5.4.0.0" />
  </dependentAssembly>

I have then added this code inside the Global.asax (it's now in the Application_BeginRequest() in order to make it go through at every page load, it will be then inside the Application_Start method):

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
            modelBuilder.EntitySet<Product>("Products");

            Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();
            try { 
                GlobalConfiguration.Configuration.Routes.MapODataRoute("ODataRoute", "xxxWebClient/api/1.0.0/projectid", model); 
            }

the point is that when I target my odata controller url I get a 406 (not acceptable) status code. (for instance 'xxxWebClient/api/1.0.0/projectid/Products').

The definition of my controller is like:

public class ProductsController : AsyncEntitySetController<Product, string>
{

I have successfully tested this AsyncEntitySetController on a blank test project, I would like to be able to integrate it with Areas. Any ideas are greatly appreciated. Thanx.

Это было полезно?

Решение

It seems that, according to the only resource I have found on this topic, what I want to accomplish is not yet possible. See GrahameHorner's comment and its reply HERE. I have anyway found a workaround for my problem, which is not to use the AsyncEntitySetController, but instead go for the ApiController as before, passing the ODataQueryOptions as parameter of the controller, so they would be automatically parsed by the WebAPI. I have then the C# ODataQueryOptions object which I can apply to whatever I want. Example controller class definition and method:

public class ProductsController : ApiController
{
    public IEnumerable<Keyword> GetKeywords(ODataQueryOptions<xxx.yyy.Keyword> options)
    {
      //my controller stuff
    }
}    

Note I am casting the ODataQueryOptions to the target type I want to apply the options to.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top