首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# OData GetKeyFromUri -找不到段'odata‘的资源

C# OData GetKeyFromUri -找不到段'odata‘的资源
EN

Stack Overflow用户
提问于 2018-11-11 02:03:53
回答 2查看 756关注 0票数 1

我已经从Microsoft.AspNet.OData版本6.0.0更新到OData版本7.0.1。升级破坏了我在将一个对象链接到另一个对象时从路径获取Id的能力。下面是我使用OData标准向特定用户添加角色的Web API调用:

代码语言:javascript
运行
复制
POST: http://localhost:61506/odata/users('bob')/roles/$ref
Request body: {"@odata.id":"http://localhost:61506/odata/roles(1)"}

Web API方法验证用户,然后调用Helpers.GetKeyFromUri从请求正文中获取角色ID值。

代码语言:javascript
运行
复制
[HttpPost, HttpPut]
public IHttpActionResult CreateRef([FromODataUri] string key, string navigationProperty, [FromBody] Uri link)
{
    // Ensure the User exists
    User user = new User().GetById(key);
    if (user == null)
    {
        return NotFound();
    }

    // Determine which navigation property to use
    switch (navigationProperty)
    {
        case "roles":
            // Get the Role id
            int roleId;
            try
            {
                roleId = Helpers.GetKeyFromUri<int>(Request, link);
            }
            catch (Exception ex)
            {
                return BadRequest();
            }

            // Ensure the Role exists
            Role role = new Role().GetById(roleId);
            if (role == null)
            {
                return NotFound();
            }

            // Add the User/Role relationship
            user.Roles.Add(role);
            user.Update();

            break;

        default:
            return StatusCode(HttpStatusCode.NotImplemented);
    }            

    return StatusCode(HttpStatusCode.NoContent);
}

该函数如下所示(最初来自此处,但具有更新的引用:https://github.com/OData/ODataSamples/blob/master/RESTier/Trippin/Trippin/Helpers.cs)

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Routing;
using Microsoft.AspNet.OData.Extensions;
using Microsoft.AspNet.OData.Routing;
using Microsoft.OData.UriParser;

namespace Project1.Extensions
{
    public class Helpers
    {
        public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)
        {
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }

            var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);

            var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));

            string serviceRoot = urlHelper.CreateODataLink(
                request.ODataProperties().RouteName,
                pathHandler, new List<ODataPathSegment>());
            var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

            var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
            if (keySegment == null)
            {
                throw new InvalidOperationException("The link does not contain a key.");
            }

            var value = keySegment.Keys.FirstOrDefault().Value;
            return (TKey)value;
        }
    }
}

此行代码现在抛出以下错误:找不到段'odata‘的资源

代码语言:javascript
运行
复制
var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

这在使用OData 6.0.0时运行良好,但在7.0.1中失败。它似乎在解析我的odata段时遇到了某种问题,或者根本找不到它。以下是我的路由设置,如果有帮助的话:

代码语言:javascript
运行
复制
public static void Register(HttpConfiguration config)
{
    // Setup the OData routes and endpoints
    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: "odata",
        model: GetEdmModel());

    // Enable OData URL querying globally
    config.Count().Filter().Select().OrderBy().Expand().MaxTop(null);
}
EN

回答 2

Stack Overflow用户

发布于 2020-05-20 04:06:57

我知道我来晚了一点,但我在升级到Microsoft.AspNet.OData 7.x时遇到了同样的问题。经过一些调试和修补,我发现这段代码对我来说是有效的--而不需要删除routePrefix:

代码语言:javascript
运行
复制
public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)
{
    if (uri == null)
    {
        throw new ArgumentNullException(nameof(uri));
    }

    var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);

    string serviceRoot = urlHelper.CreateODataLink(
        request.ODataProperties().RouteName,
        request.GetPathHandler(),
        new List<ODataPathSegment>());

    var odataPath = request.GetPathHandler().Parse(
        serviceRoot,
        uri.AbsoluteUri,
        request.GetRequestContainer());

    var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
    if (keySegment == null)
    {
        throw new InvalidOperationException("The link does not contain a key.");
    }

    return (TKey)keySegment.Keys.FirstOrDefault().Value;
}

事实证明,IODataPathHandler.Parse(...)可以接受绝对URI并根据serviceRoot解析它。

另一个关键区别是KeySegment.Keys已经有了键值的映射,其中的值已经被解析-它只需要转换即可。

作为参考,我使用的是Microsoft.AspNet.OData 7.4.0

希望这能有所帮助!

票数 0
EN

Stack Overflow用户

发布于 2018-12-21 01:11:54

我把routePrefixnull改成了odata,就像你做的那样,这也给自己造成了同样的问题。只要您不需要路由前缀(例如/odata/),将routePrefix设置为null将允许您的代码完全正常工作。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53241904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档