Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#OData GetKeyFromUri-未找到段';奥达塔';_Odata - Fatal编程技术网

C#OData GetKeyFromUri-未找到段';奥达塔';

C#OData GetKeyFromUri-未找到段';奥达塔';,odata,Odata,我已将Microsoft.AspNet.OData版本6.0.0更新为OData版本7.0.1。升级破坏了我在将一个对象链接到另一个对象时从路径获取Id的能力。以下是使用OData标准向特定用户添加角色的Web API调用: POST: http://localhost:61506/odata/users('bob')/roles/$ref Request body: {"@odata.id":"http://localhost:61506/odata/roles(1)"} Web API方法

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

POST: http://localhost:61506/odata/users('bob')/roles/$ref
Request body: {"@odata.id":"http://localhost:61506/odata/roles(1)"}
Web API方法验证用户,然后调用Helpers.GetKeyFromUri从请求主体获取角色Id值

[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);
}
这在使用OData6.0.0时运行良好,但在7.0.1中失败。解析我的odata段或根本找不到它似乎有点问题。以下是我的路由设置(如果有帮助):

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);
}

我将
routePrefix
null
更改为
odata
也造成了同样的问题,就像您所做的那样。只要不需要路由前缀(如
/odata/
),将
routePrefix
设置为
null
将允许代码正常工作

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

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;
}
公共静态TKey GetKeyFromUri(HttpRequestMessage请求,Uri)
{
if(uri==null)
{
抛出新ArgumentNullException(nameof(uri));
}
var urlHelper=request.GetUrlHelper()??新的urlHelper(请求);
字符串serviceRoot=urlHelper.CreateODataLink(
request.ODataProperties().RouteName,
request.GetPathHandler(),
新列表());
var odataPath=request.GetPathHandler().Parse(
serviceRoot,
uri.AbsoluteUri,
GetRequestContainer());
var keySegment=odataPath.Segments.OfType().FirstOrDefault();
if(keySegment==null)
{
抛出新的InvalidOperationException(“链接不包含密钥”);
}
返回(TKey)keySegment.Keys.FirstOrDefault()值;
}
事实证明,它可以获取一个绝对URI并根据serviceRoot解析它

另一个关键区别是KeySegment.Keys已经有了键值的映射,其中的值已经被解析了——只需要对其进行强制转换

作为参考,我使用的是7.4.0

希望这有帮助

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);
}
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;
}