【问题标题】:Using A Service DB Context as WebApi OData Context使用服务数据库上下文作为 WebApi OData 上下文
【发布时间】:2015-06-05 17:31:37
【问题描述】:

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

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。

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

【问题讨论】:

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


    【解决方案1】:

    显然,仅通过以下方式启用 OData 支持:

    config.AddODataQueryFilter();
    

    在本地工作,但如果来自服务,您需要明确声明您的模型。我不是 100% 确定这是我所有问题的原因,我最终调试了 System.Web.Http.OData 和 .net 4.5 框架,发现根本原因是 DefaultContentNegotiator.cs 一直说它不能Iqueryable 类型,因为请求无法解析 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();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多