我正在尝试使用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。
有没有人知道我能做些什么来解决这个问题?
答案 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();
}