"' HttpRequestMessageProperties'不包含' PathHandler'"的定义尽管使用System.Web.Odata.Extensions

时间:2017-07-14 15:11:15

标签: c# asp.net odata visual-studio-2017

我目前正在学习如何使用MS's ASP.NET web API guide 创建OData服务。在“帮助程序”部分中,尝试抓取字段HttpRequestMessage.ODataProperties().PathHandler...Model会引发上述错误。根据{{​​3}},导入System.Web.OData.Extensions应该是正确的。

使用适用于Odata.Client的6.13.0和适用于Odata.Core的7.0.0。

相关代码,基本上是1:1的web api指南:

using Microsoft.OData;
using Microsoft.OData.UriParser;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Routing;
using System.Web.OData.Extensions;

namespace WebApiGuide {
public static 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);

        string serviceRoot = urlHelper.CreateODataLink(
            Request.ODataProperties().RouteName,
            Request.ODataProperties().PathHandler, new List<ODataPathSegment>());
        var odataPath = Request.ODataProperties().PathHandler.Parse(
            Request.ODataProperties().Model,
            serviceRoot, uri.LocalPath);

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

        var value = ODataUriUtils.ConvertFromUriLiteral(keySegment.Value, ODataVersion.V4);
        return (TKey)value;
    }
}
}

修改:如果它使问题更具体,我在[{1}}

中的KeyValuePathSegment遇到了同样的问题

3 个答案:

答案 0 :(得分:2)

对于其他出于与我相同的原因而出现在此处的人,这是我的代码(显然keySegment也已更改,而Value包含已转换的对象):

public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)
{
    if (uri == null)
    {
        throw new ArgumentNullException(nameof(uri));
    }

    var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);
    var serviceRoot = urlHelper.CreateODataLink(request.ODataProperties().RouteName, request.GetPathHandler(), new List<ODataPathSegment>());
    var odataPath = request.GetPathHandler().Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

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

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

答案 1 :(得分:1)

这是一个老问题,但您可以在HttpRequestMessage类上使用Request.ODataProperties().PathHandler扩展方法。因此,您可以使用Request.GetPathHandler()而不是{{1}}。

我希望这可以帮助其他人解决这个问题。

答案 2 :(得分:0)

如果您使用Microsoft.AspNet.OData.ODataControllerODataController继承自Microsoft.AspNetCore.Mvc.ControllerBase。在此基本控制器类中,找不到HttpRequestMessage,而找不到HttpRequest。因此,您需要修改更多代码:

    public static Microsoft.AspNet.OData.Routing.ODataPath CreateODataPath(this HttpRequest request, Uri uri)
    {
        var pathHandler = request.GetPathHandler();
        var serviceRoot = request.GetUrlHelper().CreateODataLink(
                                request.ODataFeature().RouteName,
                                pathHandler,
                                new List<ODataPathSegment>());

        return pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());
    }

    public static TKey GetKeyValue<TKey>(this HttpRequest request, Uri uri)
    {
        if (uri == null)
        {
            throw new ArgumentNullException("uri");
        }

        //get the odata path Ex: ~/entityset/key/$links/navigation
        var odataPath = request.CreateODataPath(uri);
        var keySegment = odataPath.Segments.OfType<KeySegment>().LastOrDefault();
        if (keySegment == null)
        {
            throw new InvalidOperationException("This link does not contain a key.");
        }

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

此代码的一部分来自https://stackoverflow.com/a/54111132/196526,您可以在其中获取更多信息。也许。