使用服务数据库上下文作为WebApi OData上下文

时间:2015-06-05 17:31:37

标签: c# wcf odata asp.net-web-api2

我正在尝试使用Webapi 2创建OData服务。 我已经创建了一个适用于本地上下文的工作示例。现在,我想使用从单独的WCF服务提供的Context。

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();
    }

控制器类:

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)
    {
    }
}

很抱歉,这些评论只是我尝试的其他解决方案。

当我得到执行代码时,我收到406不可接受的错误或我得到一个空身而不是我的Json。

有没有人知道我能做些什么来解决这个问题?

1 个答案:

答案 0 :(得分:0)

显然只需使用:

即可启用OData支持
config.AddODataQueryFilter();

在本地工作,但如果来自服务,则需要明确声明模型。我不是百分之百确定这是我所有问题的原因,我最终调试了System.Web.Http.OData和.net 4.5框架,发现根本原因是DefaultContentNegotiator.cs一直说它不能Iqueryable类型,因为Request无法解析EDM模型。在明确地宣布我的模型之后,一切都开始起作用了:

 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();
    }