添加新的OData控制器出现故障现有控制器 [英] Adding a new OData controller fails existing controller

查看:312
本文介绍了添加新的OData控制器出现故障现有控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立从两个Web API的OData采样的采样,他们每个人作为一个单独的项目工作正常。但是,当我添加第二ODataController类,那么该网站不再起作用抱怨说pviously工作$ P $ OData的路径模板。以下是详细信息:

I am building a sample from two Web API OData samples, each of them works fine as a separate project. But when I add second ODataController class, then the site no longer works complaining about OData path templates that worked previously. Here are more details:

以下行动工作正常,只要它的控制器(ProductsController的)是唯一的控制器:

The following action works fine as long as its controller (ProductsController) is the only controller:

[HttpGet]
[ODataRoute("GetSalesTaxRate(state={state})")]
public IHttpActionResult GetSalesTaxRate([FromODataUri] string state)
{
    return Ok(GetRate(state));
}

现在我有几个动作添加一个新的控制器(MoviesController)。

Now I add a new controller (MoviesController) with a few actions.

我延长Owin启动类,所以它看起来是这样的:

I extend Owin Startup class so it looks like this:

public void Configuration(IAppBuilder builder)
{
    var config = new HttpConfiguration();

    config.MapODataServiceRoute(routeName: "functions route", routePrefix: "functions", model: FunctionStartup.GetEdmModel());
    config.MapODataServiceRoute(routeName: "actions route", routePrefix: "actions", model: ActionStartup.GetEdmModel());

    builder.UseWebApi(config);
}

然而,当我尝试执行Web请求(URLBASE /功能/ $元数据),我收到以下错误:

However, when I try to execute a Web request (URLBASE/functions/$metadata), I get the following error:

System.InvalidOperationExceptionThe路径模板
  GetSalesTaxRate(州= {}状态)在行动GetSalesTaxRate在
  控制器产品不是一个有效的路径OData的模板。资源不
  发现该段GetSalesTaxRate。

System.InvalidOperationExceptionThe path template 'GetSalesTaxRate(state={state})' on the action 'GetSalesTaxRate' in controller 'Products' is not a valid OData path template. Resource not found for the segment 'GetSalesTaxRate'.

控制器被映射到不同的途径(功能和行动)。可以是,该问题是,每个路由映射到其自己的EdmModel

Controllers are mapped to different routes ("functions" and "actions"). Can be that the problem is that each route is mapped to its own EdmModel?

更新。我检查,我可以,只要它们指的是同一个型号的EDM添加更多的控制器。但是,一旦我介绍第二个模型(从MapODataServiceRoute引用它),那么整个服务中断。有什么解决方法,以支持多种模式?

UPDATE. I checked that I can add more controllers as long as they refer to the same EDM model. But once I introduce a second model (and reference it from MapODataServiceRoute), then the whole service breaks. Is there any workaround to support multiple models?

更新2.如果我继承DefaultHttpControllerTypeResolver只有启用单控制器(任何人),那么也能正常工作。但我仍然不解,为什么使用不同的模型多个控制器失败。

UPDATE 2. If I subclass DefaultHttpControllerTypeResolver and only enable single controller (any of them), then is also works fine. But I am still puzzled why multiple controllers using different models fail.

推荐答案

默认情况下,地图的OData属性路线约定,HTTP控制器选择IHttpControllerSelector默认的逻辑使用HttpConfiguration的DefaultAssembloesResolver,这将查找所有控制器类型的应用程序域。范围可以降低到控制器属于一种模式。

By default, when map OData attribute route conventions, the default logic of HTTP controller selector IHttpControllerSelector uses HttpConfiguration's DefaultAssembloesResolver, which will look up all controller types in an app domain. The scope could be reduced to controllers belong to a model.

我们可以自定义MapODataServiceRoute扩展方法。有些code片断:

We can customize the MapODataServiceRoute extension methods. Some code snippet:

public class Startup
{
    public void Configuration(IAppBuilder builder)
    {
        var config = new HttpConfiguration();

        config.CustomMapODataServiceRoute(routeName: "functions route", routePrefix: "functions",
            model: FunctionStartup.GetEdmModel(),
            controllers: new[] { typeof(ProductsController) });
        config.CustomMapODataServiceRoute(routeName: "actions route", routePrefix: "actions",
            model: ActionStartup.GetEdmModel(),
            controllers: new[] { typeof(MoviesController) });

        config.EnsureInitialized();

        builder.UseWebApi(config);
    }
}

public class CustomAttributeRoutingConvention : AttributeRoutingConvention
{
    private readonly List<Type> _controllers = new List<Type> { typeof(MetadataController) };

    public CustomAttributeRoutingConvention(IEdmModel model, HttpConfiguration configuration, IEnumerable<Type> controllers)
        : base(model, configuration)
    {
        _controllers.AddRange(controllers);
    }

    public override bool ShouldMapController(HttpControllerDescriptor controller)
    {

        return _controllers.Contains(controller.ControllerType);
    }
}

public static class HttpConfigExt
{
    public static ODataRoute CustomMapODataServiceRoute(this HttpConfiguration configuration, string routeName,
        string routePrefix, IEdmModel model, IEnumerable<Type> controllers)
    {
        var routingConventions = ODataRoutingConventions.CreateDefault();
        routingConventions.Insert(0, new CustomAttributeRoutingConvention(model, configuration, controllers));
        return configuration.MapODataServiceRoute(routeName, routePrefix, model, new DefaultODataPathHandler(),
            routingConventions);
    }
}

这篇关于添加新的OData控制器出现故障现有控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆