【发布时间】:2016-03-30 06:12:18
【问题描述】:
我查看了所有关于此的 SO 帖子,但没有成功。我可以调用OData 控制器并查看检索、映射和打包的数据。控制器方法退出,我得到一个406 - Not Acceptable。我只使用 System.Web.OData 命名空间(OData 版本 v4.0.30319),并且使用 Postman,我手动将 Content 和 Accept 标头设置为 'application/ json' 没有运气
在过去的 2 个小时里,我可能错过了一些关于类似问题的帖子。任何指针将不胜感激。
更新:
问题似乎出在 Mapper 代码 (Automapper) 中,如下 Igor 所指出。看起来有承诺返回数据库(EF)实体,而不是映射类。有了这些知识,我找到了这个 SO 帖子,但它没有提供解决方案:ApiController vs ODataController when exposing DTOs。我们是否不得不返回数据库实体或者可以映射结果?如果是这样,那对我来说就是一个交易破坏者。
控制器:
[EnableQuery]
[HttpGet]
public async Task<IHttpActionResult> Get()
{
var list = await db.ConfigSets.ToListAsync();
Mapper.CreateMap<ConfigSet, ConfigSetDTO>();
var configSetDTOs = Mapper.Map<List<ConfigSet>, List<ConfigSetDTO>>(list);
return Ok(configSetDTOs); //IT LOOKS GOOD HERE!
}
WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.EnableCors();
// OData - must be before config.Routes when using a prefix. In this case "api"
config.MapODataServiceRoute("odata", "api", GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.Namespace = "Services";
builder.ContainerName = "DefaultContainer";
builder.EntitySet<ConfigSet>("Configuration");
var edmModel = builder.GetEdmModel();
return edmModel;
}
}
【问题讨论】:
-
我不确定
Mapper.Map返回什么,但无论它是什么,它都应该实现IQueryable或其中的泛型。您是否尝试过使用硬编码的List<ConfigSetDTO>实例进行测试,并在return调用中返回Ok(myList.AsQueryable());?这应该可以帮助您缩小问题所在,整体配置或您尝试返回的数据的数据或格式。 -
@Igor..Mapper 是 Automapper。我在没有它的情况下尝试了这段代码以及您的建议并得到了相同的结果。
-
我想我明白了。
builder.EntitySet<ConfigSet>("Configuration");表示应该从 Get() 方法返回的预期类型是ConfigSet类型,但您返回的是ConfigSetDTO类型。要查看这是否确实是问题,请尝试返回ConfigSet实例的硬编码列表,但在Ok方法中调用AsQueryable()。 IE;return Ok(myConfigSetList.AsQueryable()); -
@Igor...你在做某事。映射一定是问题,因为它有效: var list = await db.ConfigSets.ToListAsync();return Ok(list);
-
除了从 SQL 视图中提取的 EF 数据之外,我从未使用过来自 oData 的 Get() 函数,因此我不确定什么是可能的或不可能的。据我了解,整个目的是 MS Odata Web API 控制器根据传入的 URL 处理所有查询逻辑,这就是为什么您希望将 oData 与 Get-er 函数一起使用,因为它提供了一种标准方法查询数据,不需要额外的代码来过滤后端,并且过滤发生在数据库而不是内存中。如果你在这之间推动像 Automapper 这样的东西,我怀疑它会起作用。
标签: asp.net-web-api odata asp.net-web-api2 automapper