【问题标题】:ODataController returning HTTP 406 Not AcceptableODataController 返回 HTTP 406 不可接受
【发布时间】:2015-07-10 14:57:18
【问题描述】:

我正在 Web API 2.2 上构建 OData 3 服务。

该服务正在正确返回我的实体的元数据,但在我查询其中一个实际实体时返回 406 Not Available。我已经做了很多研究(我目前正在学习几个教程),但我还没有找到任何真正有效的东西。

这是我的 WebApiConfig:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;

namespace MyProject
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntitySet<MarvelCharacter>("MarvelCharacters");
            config.MapODataServiceRoute(
                routeName: "Marvel",
                routePrefix: "dude",
                model: builder.GetEdmModel());
        }
    }
}

还有我的控制器(不完整,但你明白了):

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Query;
using Microsoft.Data.OData;
using MyProject;

namespace MyProject.Controllers
{
    public class MarvelCharactersController : ODataController
    {
        private static ODataValidationSettings _validationSettings = new ODataValidationSettings();

        // GET: odata/MarvelCharacters
        public IHttpActionResult GetMarvelCharacters(ODataQueryOptions<MarvelCharacter> queryOptions)
        {
            // validate the query.
            try
            {
                queryOptions.Validate(_validationSettings);
            }
            catch (ODataException ex)
            {
                return BadRequest(ex.Message);
            }

            var entities = new myEntities();
            var marvelCharacters = (from c in entities.MarvelCharacters select c).ToList();

            return Ok<IEnumerable<MarvelCharacter>>(marvelCharacters);
        }
    }
}

【问题讨论】:

    标签: c# .net asp.net-web-api odata http-status-code-406


    【解决方案1】:

    事实证明,这个问题的答案非常简单,但我能找到的任何文档都没有很好地涵盖。

    我试图在 WebAPI 2.2 上实现 OData 3 端点。我正在学习几个不同的教程,一些针对 OData 3,一些针对 OData 4。

    我在 WebApiConfig 中使用 OData 4 (System.Web.OData),在控制器中使用 OData 3 (System.Web.Http.OData)。事实证明,他们在一起玩得不好。

    我决定在这里发布答案,以防其他人有类似的问题。

    为了增加一点价值,因为无论如何我都混合使用了,所以我决定继续设置对版本 3 和 4 的支持,方法是在我的 WebApiConfig 中为命名空间设置别名,然后创建版本化控制器。

    WebApiConfig:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    using ODataV3 = System.Web.Http.OData;
    using ODataV4 = System.Web.OData;
    
    namespace MyProject
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // OData V3 Route
    
                ODataV3.Builder.ODataModelBuilder builder3 = new ODataV3.Builder.ODataConventionModelBuilder();
    
                builder3.EntitySet<MarvelCharacter>("MarvelCharactersV3");
                // The MapODataRoute function is deprecated in WebAPI 2.2,
                // but I haven't found an alternative for supporting OData 3.
                config.Routes.MapODataRoute(
                    routeName: "Marvel3",
                    routePrefix: "dude3",
                    model: builder3.GetEdmModel());
    
                // ODate V4 Route
    
                ODataV4.Builder.ODataModelBuilder builder4 = new ODataV4.Builder.ODataConventionModelBuilder();
    
                builder4.EntitySet<MarvelCharacter>("MarvelCharactersV4");
                ODataV4.Extensions.HttpConfigurationExtensions.MapODataServiceRoute(
                    configuration: config,
                    routeName: "Marvel4",
                    routePrefix: "dude4",
                    model: builder4.GetEdmModel());
            }
        }
    }
    

    MarvelCharactersV3 (OData 3):

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using System.Web.Http.OData; // OData V3
    using System.Web.Http.OData.Query;
    using Microsoft.Data.OData;
    using MyProject;
    
    namespace MyProject.Controllers
    {
        public class MarvelCharactersV3Controller : ODataController
        {
            private static ODataValidationSettings _validationSettings = new ODataValidationSettings();
    
            // GET: odata/MarvelCharacters
            public IHttpActionResult GetMarvelCharactersV3(ODataQueryOptions<MarvelCharacter> queryOptions)
            {
                // validate the query.
                try
                {
                    queryOptions.Validate(_validationSettings);
                }
                catch (ODataException ex)
                {
                    return BadRequest(ex.Message);
                }
    
                var entities = new myEntities();
                var marvelCharacters = (from c in entities.MarvelCharacters select c).ToList();
    
                return Ok<IEnumerable<MarvelCharacter>>(marvelCharacters);
            }
        }
    }
    

    MarvelCharactersV4 (OData 4):

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using System.Web.OData; // OData 4
    using System.Web.OData.Query;
    using Microsoft.Data.OData;
    using MyProject;
    
    namespace MyProject.Controllers
    {
        public class MarvelCharactersV4Controller : ODataController
        {
            private static ODataValidationSettings _validationSettings = new ODataValidationSettings();
    
            // GET: odata/MarvelCharacters
            public IHttpActionResult GetMarvelCharactersV4(ODataQueryOptions<MarvelCharacter> queryOptions)
            {
                // validate the query.
                try
                {
                    queryOptions.Validate(_validationSettings);
                }
                catch (ODataException ex)
                {
                    return BadRequest(ex.Message);
                }
    
                var entities = new myEntities();
                var marvelCharacters = (from c in entities.MarvelCharacters select c).ToList();
    
                return Ok<IEnumerable<MarvelCharacter>>(marvelCharacters);
            }
        }
    }
    

    它可能不是最好的架构(我可能会创建一个库来整合控制器之间的类似代码),但我已经测试过,我可以通过 OData 3 和 OData 4 成功查询,所以我很满意它暂时。

    【讨论】:

    • 我有点希望微软实际上使用了 'OdataV3' 和 'OdataV4' 命名空间,而不是在这里塞进新版本,并且有无为 +1 的别名 - 好主意
    • 我遇到了同样的问题,首先使用 oData v3 进行设置,然后移至 oData v4,使用 V4 创建的控制器开始出现 406 错误。再次使用 V3 创建了一个控制器来验证问题,是的,它开始工作了。现在为所有人升级到 V4。
    • 非常感谢!
    • 非常感谢 JDB。微软的命名空间分配很疯狂,而且文档也很糟糕。
    猜你喜欢
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    • 2015-03-17
    • 1970-01-01
    相关资源
    最近更新 更多