gpt4 book ai didi

c# - 如何在 ASP.NET Web API 实现中将数组传递给 OData 函数?

转载 作者:可可西里 更新时间:2023-11-01 07:53:27 26 4
gpt4 key购买 nike

OData V4 的规范声明它必须是可能的: https://issues.oasis-open.org/browse/ODATA-636 .

"Complex types and arrays can only be passed to functions through parameter aliases"

当我尝试传递一个带有 OData 参数别名的数组时,发生异常。

/TestEntities/NS.TestFunction(ArrayHere=@p)?@p=[1,2,3]

结果:

Unable to cast object of type 'EdmValidCoreModelPrimitiveType' to type 'Microsoft.OData.Edm.IEdmStructuredType

有趣的是元数据文档是为这种情况正确组成的:

<Function Name="TestFunction" IsBound="true">
<Parameter Name="bindingParameter" Type="Collection(NS.TestEntity)"/>
<Parameter Name="ArrayHere" Type="System.Int32[]"/>
<ReturnType Type="Collection(NS.TestEntity)"/>
</Function>

是否可以使用 ASP.NET MVC Web API 2 OData 将数组传递给查询字符串中的 OData 函数?

更新:

这是构建 EDM 模型和 Controller 的代码。

 var builder = new ODataConventionModelBuilder();

builder.Namespace = "NS";

builder.EntitySet<TestEntity>("TestEntities");

builder.EntityType<TestEntity>().Collection
.Function("TestFunction")
.ReturnsCollectionFromEntitySet<TestEntity>("TestEntities")
.Parameter<int[]>("ArrayHere");

Controller :

public class TestEntitiesController : ODataController
{
public IEnumerable<TestEntity> TestFunction(int[] arrayHere)
{
throw new NotImplementedException();
}
}

[FromODataUri] 标记参数并不能解决问题。

更新 2:

这是堆栈跟踪:

at Microsoft.OData.Core.UriParser.TypePromotionUtils.CanConvertTo(SingleValueNode sourceNodeOrNull, IEdmTypeReference sourceReference, IEdmTypeReference targetReference)
at Microsoft.OData.Core.UriParser.Parsers.MetadataBindingUtils.ConvertToTypeIfNeeded(SingleValueNode source, IEdmTypeReference targetTypeReference)
at Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindSegmentParameters(ODataUriParserConfiguration configuration, IEdmOperation functionOrOpertion, ICollection`1 segmentParameterTokens)
at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.TryBindingParametersAndMatchingOperation(String identifier, String parenthesisExpression, IEdmType bindingType, ODataUriParserConfiguration configuration, ICollection`1& boundParameters, IEdmOperation& matchingOperation)
at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.TryCreateSegmentForOperation(ODataPathSegment previousSegment, String identifier, String parenthesisExpression)
at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreateNextSegment(String text)
at Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.ParsePath(ICollection`1 segments)
at Microsoft.OData.Core.UriParser.Parsers.ODataPathFactory.BindPath(ICollection`1 segments, ODataUriParserConfiguration configuration)
at Microsoft.OData.Core.UriParser.ODataUriParser.ParsePathImplementation()
at Microsoft.OData.Core.UriParser.ODataUriParser.Initialize()
at System.Web.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel model, String serviceRoot, String odataPath, Boolean enableUriTemplateParsing)
at System.Web.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel model, String serviceRoot, String odataPath)
at System.Web.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)
at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)

最佳答案

假设您使用的是 OData V4,则需要使用 CollectionParameter注册函数时,你错过了 [FromODataUri]在 arrayHere 参数上。另外,尝试使用 IEnumerable<int>而不是数组。

var builder = new ODataConventionModelBuilder();

builder.Namespace = "NS";

builder.EntitySet<TestEntity>("TestEntities");

builder.EntityType<TestEntity>().Collection
.Function("TestFunction")
.ReturnsCollectionFromEntitySet<TestEntity>("TestEntities")
.CollectionParameter<int>("ArrayHere");

Controller 中的函数是这样的...

[HttpGet]
public async Task<IHttpActionResult> TestFunction([FromODataUri] IEnumerable<int> ArrayHere)
{
// Do stuff
}

现在您可以提出请求,例如...

http://yourRestService/API/TestEntities/NS.TestFunction(ArrayHere=[1,2,3])

请注意,您也可以接受复杂类型的数组。你必须对数组的 json 进行 url 编码并使用参数别名,这样你最终会得到这样的东西......

 builder.EntityType<TestEntity>().Collection
.Function("TestFunction2")
.ReturnsCollectionFromEntitySet<TestEntity>("TestEntities")
.CollectionParameter<person>("ArrayHere");

[HttpGet]
public async Task<IHttpActionResult> TestFunction2([FromODataUri] IEnumerable<person> ArrayHere)
{
// Do stuff
}

http://yourRestService/API/TestEntities/NS.TestFunction2(ArrayHere=@ArrayData)?@ArrayData=%5B%7B%22FirstName%22%3A%22Bob%22%2C+%22LastName%22%3A%22Dole%22%7D%2C%7B%22FirstName%22%3A%22Bill%22%2C+%22LastName%22%3A%22Clinton%22%7D%5D

关于c# - 如何在 ASP.NET Web API 实现中将数组传递给 OData 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26634730/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com