简体   繁体   中英

Using A Service DB Context as WebApi OData Context

I'm trying create a OData service using Webapi 2. I've already created a working example that works with a local context. Now, I want to use a Context Provided from a seperate WCF Service.

WebApiConfig.cs:

public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

        config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
        config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;


        config.AddODataQueryFilter();

        // To disable tracing in your application, please comment out or remove the following line of code
        // For more information, refer to: http://www.asp.net/web-api
        config.EnableSystemDiagnosticsTracing();
    }

Controller Class:

public class ProductsController : ODataController
{
    static Uri ServiceRoot = new Uri("http://localhost:4684/BDBWcfService.svc/");

    public ProductsController()
    {
        //db.Configuration.ProxyCreationEnabled = false;
        InitDB();
    }

    public void InitDB()
    {
         db = new BDBODataService.NORTHWNDEntities(ServiceRoot);
    }

    DataServiceContext Context = new DataServiceContext(ServiceRoot, DataServiceProtocolVersion.V3);

    BDBODataService.NORTHWNDEntities db = null;

    //NORTHWNDEntities db = new NORTHWNDEntities();
    // GET api/values
    //[EnableQuery]
    //public IQueryable<Product> Get()
    //{
    //    return db.Products;
    //}

    [EnableQuery]
    public IQueryable<BDBODataService.Product> Get()
    {
        return db.Products;
        //return Context.CreateQuery<BDBODataService.Product>("Products");
    }






    // GET api/values/5

    //Naming the attribute as key allows the model binder to sync when
    // calling urls like http://localhost:7428/odata/Products(1) key here = 1

    //[EnableQuery(MaxExpansionDepth=3)]
    //public SingleResult<Product> Get([FromODataUri]int key)
    //{
    //    var res = db.Products.Where(p => p.ProductID == key);
    //    return SingleResult.Create(res);
    //}

    // POST api/values
    public void Post([FromBody]string value)
    {
    }

    // PUT api/values/5
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/values/5
    public void Delete(int id)
    {
    }
}

Sorry for the comments they are just other solutions I've tried.

When Ever I got To Execute the code I either receive 406 not acceptable error or I get an Empty Body instead of my Json.

Does any body know what I can do to fix this?

So apparently Enabling OData Support by just using:

config.AddODataQueryFilter();

does work locally but you need to explicitly declare your model if coming from a service. I'm not 100% sure that was the cause of all my problems, I ended up debugging the System.Web.Http.OData and .net 4.5 framework and found the root cause was that DefaultContentNegotiator.cs kept saying it couldn't the Iqueryable type, because the the Request couldn't resolve the EDM Model. After Explicitly declaring my model like this everything started working:

 public static IEdmModel GetServiceModel()
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

        builder.EntitySet<BDBODataService.Order>("Orders");

        /* this explicitly Ignores a specific property.
         * notice if you call http://localhost:7428/odata/Products(1)?$expand=Category
         * picture will be hidden */

        var cat = builder.EntitySet<BDBODataService.Category>("Categories");
        cat.EntityType.Ignore(c => c.Picture);

        builder.EntitySet<BDBODataService.CustomerDemographic>("CustomerDemographics");
        builder.EntitySet<BDBODataService.Customer>("Customers");
        builder.EntitySet<BDBODataService.Employee>("Employees");
        builder.EntitySet<BDBODataService.Order_Detail>("OrderDetails");
        builder.EntitySet<BDBODataService.Region>("Regions");
        builder.EntitySet<BDBODataService.Shipper>("Shippers");
        builder.EntitySet<BDBODataService.Supplier>("Suppliers");
        builder.EntitySet<BDBODataService.Territory>("Territories");
        builder.EntitySet<BDBODataService.Orpan>("Orphans");


        var products = builder.EntitySet<BDBODataService.Product>("Products");

        return builder.GetEdmModel();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM