c# – 仅为路由公开.NET OData API的子集(对于排除的API,返回404)

栏目: ASP.NET · 发布时间: 7年前

内容简介:翻译自:https://stackoverflow.com/questions/51314002/expose-only-a-subset-of-net-odata-apis-for-a-route-return-404-for-excluded-api

背景/环境:

我们有两条路线,路线前缀不同:

>路由1前缀:/ api

>路由2前缀:/ api / partial

目前,我们对两个路由前缀使用相同的EdmModel. (参见第一个代码snippit,名为“我们目前正在做什么”).

我们想要什么:

我们只需要为Route 2允许API功能的子集:/ api / partial.当有人试图访问“部分”EdmModel不可用的API时,我们希望返回404

例:

>我们希望为/ api / parial / products返回404,其中产品未在此“部分”API路径中定义.

>我们仍希望将/ api / products路由到控制器方法

我们尝试过的:

使用第二个EdmModel,它只包含完整EdmModel中可用实体的子集. (参见第二个代码snippit,名为“我们想做什么:”.)

问题:

我们在服务启动时遇到错误:

控制器“产品”中操作“导出”的路径模板“产品”不是有效的OData路径模板.未找到该段“产品”的资源.)

我对正在发生的事情的最好猜测是.NET OData库扫描所有OData控制器,函数和操作,并期望每个路由都在EdmModel中明确定义它们.如果这是真的,那么这个解决方案(初始化一个新的EdmModel)可能不会起作用……

这不受支持吗?如果没有,还有什么其他选择来实现这一目标?我们必须在控制器API函数中显式返回404吗?这需要分析API函数中“api / subset”的路径,这在我看来就像是一个hack.

我们目前的工作:

private static IEdmModel GetFullEdmModel()
{
    var builder = new ODataConventionModelBuilder();

    var orders = builder.EntitySet<Order>("orders");
    orders.EntityType.HasKey(o => o.Id);
    orders.EntityType.Property(o => o.Id).Name = "id";

    var products = builder.EntitySet<Product>("products");
    products.EntityType.HasKey(p => p.Id);
    products.EntityType.Property(p => p.Id).Name = "id";
    products.EntityType.Action("Export").Returns<ExportResponse>();

    return builder.GetEdmModel();
}

protected override void Register(HttpConfiguration config)
{
    base.Register(config);

    var model = GetFullEdmModel();
    var conventions = ODataRoutingConventions.CreateDefaultWithAttributeRouting(config, model);

    // Map route 1 to {model}
    config.MapODataServiceRoute(
        routeName: "route1",
        routePrefix: "/api",
        model: model, 
        pathHandler: new CustomBIODataPathHandler(), 
        routingConventions: conventions);

    // Map route 2 to {model}
    config.MapODataServiceRoute(
        routeName: "route2",
        routePrefix: "/api/partial", // different route prefix
        model: model, // but it uses the same model
        pathHandler: new CustomBIODataPathHandler(), 
        routingConventions: conventions);
}

我们想做什么:

private static IEdmModel GetPartialEdmModel()
{
    var builder = new ODataConventionModelBuilder();

    // Include only one entity
    var orders = builder.EntitySet<Order>("orders");
    orders.EntityType.HasKey(o => o.Id);
    orders.EntityType.Property(o => o.Id).Name = "id";

    return builder.GetEdmModel();
}

protected override void Register(HttpConfiguration config)
{
    base.Register(config);

    // Map route 1 to {model}
    var model = GetFullEdmModel();
    var modelConventions = ODataRoutingConventions.CreateDefaultWithAttributeRouting(config, model);
    config.MapODataServiceRoute(
        routeName: "route1",
        routePrefix: "/api",
        model: model, // use standard full model
        pathHandler: new CustomBIODataPathHandler(), 
        routingConventions: conventions);

    // Map route 2 to a new partial model: {partialModel}    
    var partialModel = GetPartialEdmModel();
    var partialModelConventions = ODataRoutingConventions.CreateDefaultWithAttributeRouting(config, model);
    config.MapODataServiceRoute(
        routeName: "route2",
        routePrefix: "/api/partial", // different route prefix
        model: partialModel, // use a sparate, partial edm model ( a subset of the full edm model )
        pathHandler: new CustomBIODataPathHandler(), 
        routingConventions: conventions);
}

您需要两种不同的型号或更具智能的型号,因为有权使用的产品并非在所有路径中都可用,而只能在/ api / products中使用.

一般来说,错误消息已经很好地解释了它,但也许你只需要它就可以了.

我认为更清洁的方法是为每条路线提供一个自己的模型,然后很容易添加或删除你需要的内容.

如果在一个模型中混合所有内容,如果添加或更改新路径,它将始终在构建中.

// Map route 1 to {model}
config.MapODataServiceRoute(
    routeName: "route1",
    routePrefix: "/api",
    model: GetApiModel(), 
    pathHandler: new CustomBIODataPathHandler(), 
    routingConventions: conventions);


// Map route 2 to {model}
config.MapODataServiceRoute(
    routeName: "route2",
    routePrefix: "/api/partial", // different route prefix
    model: GetApiPartialModel(),
    pathHandler: new CustomBIODataPathHandler(), 
    routingConventions: conventions);

这是一个概念,我对代码中的符号并不那么坚定,所以你可能需要稍微调整一下.

或者,如果您真的只想使用一个模型,请尝试这样:

// Map route 1 to {model}
config.MapODataServiceRoute(
    routeName: "route1",
    routePrefix: "/api",
    model: GetFullEdmModel("/api"), 
    pathHandler: new CustomBIODataPathHandler(), 
    routingConventions: conventions);

// Map route 2 to {model}
config.MapODataServiceRoute(
    routeName: "route2",
    routePrefix: "/api/partial", // different route prefix
    model: GetFullEdmModel("/api/partial"), // but it uses the same model
    pathHandler: new CustomBIODataPathHandler(), 
    routingConventions: conventions);

然后,您可以使用该参数来实现任何条件或开关.

除此之外,您可能在底部的所需代码中出现错误:

// Map route 1 to {model}
var model = GetFullEdmModel();
var modelConventions = ODataRoutingConventions.CreateDefaultWithAttributeRouting(config, model);
config.MapODataServiceRoute(
    routeName: "route1",
    routePrefix: "/api",
    model: model, // use standard full model
    pathHandler: new CustomBIODataPathHandler(), 
    routingConventions: modelConventions);

查看最后一行,然后必须针对这两个块进行调整.

关于每个配置块上面的两行,我从来没有注意过,所以主要的问题可能是并非所有变量都适合在一起,你需要在所有细节中检查它.

翻译自:https://stackoverflow.com/questions/51314002/expose-only-a-subset-of-net-odata-apis-for-a-route-return-404-for-excluded-api


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Bandit Algorithms for Website Optimization

Bandit Algorithms for Website Optimization

John Myles White / O'Reilly Media / 2013-1-3 / USD 19.99

This book shows you how to run experiments on your website using A/B testing - and then takes you a huge step further by introducing you to bandit algorithms for website optimization. Author John Myle......一起来看看 《Bandit Algorithms for Website Optimization》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具