我正在尝试从我们当前的 ApiController 实现转移到 ODataController,因为这是我发现能够返回 OData Json 格式数据的唯一方法。(与这里的问题相同,但解决方案对我不起作用)
我一直在尝试锻炼 ODataController,我发现它在此之后运行良好。但是,我的项目实现了与简单“~/odata/Entity”的默认 OData 路由不同的路由。我需要将我的控制器分组到多个区域,因为有些控制器的名称重复。
在this和this之后,我能够实现自定义路由并运行它似乎到达正确的控制器并成功通过它。但是,我仍然在 Fiddler 中遇到错误
“'ObjectContent`1' 类型无法序列化内容类型 'application/json;odata=minimalmetadata;streaming=true;charset=utf-8' 的响应正文。”
除了内部的例外
无法从 OData 路径中找到相关实体集。序列化payload需要相关实体集
现在我已经被困了好几个小时了。如果没有路由处理程序,只需通过“~/odata/Entity”访问数据,我的代码就可以运行得很好。只是当我实现自定义路由时,它在通过我的控制器代码后失败。
任何帮助,将不胜感激。
这是一些代码:
全球.asax:
//Added this on App_Start
config.Services.Replace(typeof(IHttpControllerSelector), new CustomHttpControllerSelector(config));
//Snippet from RegisterRoutes
ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Entity>("Entities");
IEdmModel model = modelBuilder.GetEdmModel();
config.Routes.MapODataRoute(
routeName: "ODataDefault",
routePrefix: "{version}/{area}/{controller}", //Works since I could reach my controller
model: model);
控制器:
[HttpGet]
[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Entity> Get()
{
EntitySet entitySet = new EntitySet();
return entitySet.Entities;
}
自定义HttpControllerSelector:
承袭于此。基本上,这只是解析请求以获取特定的控制器描述符。
private HttpControllerDescriptor GetController(HttpRequestMessage request)
{
HttpControllerDescriptor descriptor = null;
IHttpRouteData routeData = request.GetRouteData();
// Get variables from the route data.
string versionName = null;
routeData.Values.TryGetValue("version", out versionName );
string areaName = null;
routeData.Values.TryGetValue("area", out areaName);
string controllerName = null;
routeData.Values.TryGetValue("controller", out controllerName);
string fullName = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", versionName, areaName, controllerName);
// Search for the controller.
// _controllerTypes is a list of HttpControllerDescriptors
var type = _controllerTypes.Where(t => t.Key.EndsWith(fullName, StringComparison.OrdinalIgnoreCase)).Select(t => t.Value).FirstOrDefault();
if (type != null)
{
descriptor = new HttpControllerDescriptor(_configuration, controllerName, type);
}
return descriptor;
}