【问题标题】:using ODataRoutePrefix and ODataRoute for OData AttributeRouting is not working对 OData AttributeRouting 使用 ODataRoutePrefix 和 ODataRoute 不起作用
【发布时间】:2021-04-09 13:49:56
【问题描述】:

注意:这不是重复的,因为我在AspNetCore 中使用的是全新的OData 实现版本。

基于 Microsoft 的 this 文章,我尝试使用 AttributeRoutingConvetion 并最终使用 ODataRoutePrefixODataRoute 使用 Asp.net Core 5 Web API 和 Microsoft.AspNetCore.OData Version="8.0.0-preview3"(请注意 版本)。

这是我的代码:

Startup.cs

 public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
           

            services.TryAddEnumerable(ServiceDescriptor.Transient<IODataControllerActionConvention, AttributeRoutingConvention>());
            services.AddOData(
                opt => opt.AddModel("odata",GetEdmModel()).Select().Count().Filter().OrderBy().SetAttributeRouting(true)
                );
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

        public IEdmModel GetEdmModel()
        {
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<WeatherForecast>("WeatherForecast2");
            return builder.GetEdmModel();
        }

这是我的控制器:

    [ODataRoutePrefix("WFC")]
    public class WeatherForecast2Controller : ODataController
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecast2Controller> _logger;

        public WeatherForecast2Controller(ILogger<WeatherForecast2Controller> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        [EnableQuery]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }


        [HttpGet]
        [EnableQuery]
        [ODataRoute("AnotherGet")]
        public IEnumerable<WeatherForecast> AnotherGet()
        {
            var rng = new Random();
            return Enumerable.Range(1, 3).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

现在我期望调用 https://localhost:44346/WFC/AnotherGet 通过执行 AnotherGet 方法返回 3 Weatherforcast 结果,但我收到 404 错误。我也尝试了以下方法:

~/odata/WeatherForecast2  -  executes Get and returns array of 5 Weatherforcast 
~/odata/WFC/              - 404 not found 
~/odata/WFC/AnotherGet    - 404 not found 
~/WFC/                    - 404 not found 
~/WFC/AnotherGet          - 404 not found 

如何执行特定的控制器及其方法?

【问题讨论】:

    标签: c# asp.net-core routes odata


    【解决方案1】:

    @nAvid

    感谢您试用 ASP.NET Core OData 8.0。

    首先,我在博客中提到:

    
     1. ODataRoutePrefixAttribute is an attribute that can, and only can be placed on an OData controller to specify the prefix that will be used for all actions of that controller.
     2. ODataRouteAttribute is an attribute that can, and only can be placed on an action of an OData controller to specify the OData URLs that the action handles.
    
    

    其次,属性中定义的the path route template 应遵循OData 约定规范。 也就是说,来自 'ODataRoutePrefixAttribute' 和 'ODataRouteAttribute' 的串联字符串应该通过 OData uri 解析器。

    举个例子:

    [ODataRoutePrefix("WFC")] 
    public class WeatherForecast2Controller : ODataController
    {
      ...
       [ODataRoute("AnotherGet")]
       public IEnumerable<WeatherForecast> AnotherGet()
       {
       }
    }
    

    操作“AnotherGet”的串联字符串是“WFC/AnotherGet”。 从 OData convention URI 开始,WFC/AnotherGet 应该是有效的 OData URI(模板)。 但是,Edm 模型(您在 GetEdmModel 中构建)没有任何相关的“WFC”或“AnotherGet”。

    所以,预计您会收到以下回复:

    • ~/odata/WFC/ - 404 未找到
    • ~/odata/WFC/AnotherGet - 404 未找到
    • ~/WFC/ - 404 未找到
    • ~/WFC/AnotherGet - 404 未找到

    对于

    • '~/odata/WeatherForecast2 - 执行 Get 并返回数组 5 Weatherforcast',

    这不是 OData 属性路由,但它可以工作,因为它是 OData 约定路由。 约定路由看起来是控制器的“EntitySetName”+控制器。 因此,public class WeatherForecast2Controller 符合该约定。 而public IEnumerable&lt;WeatherForecast&gt; Get()满足查询实体集约定路由。所以,它有效。

    【讨论】:

    • ODataRouteAttribute 在 8.0.0-rc 中消失了吗?
    • @MatthiasBurger 是的,ODataRouteAttribute 在 8.0.0 RC 中消失了。请使用 Http Verb 属性和 [RouteAttribute]。请在以下位置查看更多详细信息:devblogs.microsoft.com/odata/…
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多