C # OData GetKeyFromUri - Ресурс не найден для сегмента 'odata' - PullRequest
0 голосов
/ 10 ноября 2018

Я обновил Microsoft.AspNet.OData версии 6.0.0 до OData версии 7.0.1. Обновление сломало мою способность получать Id из пути при связывании одного объекта с другим. Вот мой вызов Web API для добавления роли конкретному пользователю с использованием стандарта OData:

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

Эта функция выглядит следующим образом (Изначально, но с обновленными ссылками: https://github.com/OData/ODataSamples/blob/master/RESTier/Trippin/Trippin/Helpers.cs)

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'

var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

Это работало нормально при использовании OData 6.0.0, но не работает в 7.0.1. Кажется, у меня какая-то проблема с анализом моего сегмента данных или невозможностью его найти вообще. Вот мои настройки маршрутизации, если это поможет:

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

1 Ответ

0 голосов
/ 20 декабря 2018

Я вызвал у себя ту же проблему, изменив routePrefix с null на odata, как вы сделали. Установка routePrefix в null позволит вашему коду работать безупречно, если вам не нужен префикс маршрута (например, /odata/).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...