我目前正在学习如何使用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
遇到了同样的问题
答案 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.ODataController
。 ODataController
继承自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,您可以在其中获取更多信息。也许。