【发布时间】:2014-12-25 09:58:51
【问题描述】:
OData V4 的规范声明它必须是可能的: https://issues.oasis-open.org/browse/ODATA-636.
"复杂类型和数组只能通过 参数别名”
当我尝试传递带有 OData 参数别名的数组时,会发生异常。
/TestEntities/NS.TestFunction(ArrayHere=@p)?@p=[1,2,3]
结果:
无法将“EdmValidCoreModelPrimitiveType”类型的对象转换为类型 '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 模型和控制器的代码。
var builder = new ODataConventionModelBuilder();
builder.Namespace = "NS";
builder.EntitySet<TestEntity>("TestEntities");
builder.EntityType<TestEntity>().Collection
.Function("TestFunction")
.ReturnsCollectionFromEntitySet<TestEntity>("TestEntities")
.Parameter<int[]>("ArrayHere");
控制器:
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)
【问题讨论】:
-
你能贴出抛出异常的代码吗?
-
有趣的问题,我真的很高兴看到您用于将函数添加到 $metadata 和函数实现的代码。
-
@gdoron,请查看更新后的问题
-
@PseudoNym01,请查看更新后的问题
-
我有类似的代码,但使用 CollectionParameter
() 而不是 Parameter ()。它不会抛出异常,但传递给控制器中自定义函数的值始终为 null(无论我将其定义为 int[] 还是 IEnumerable 还是 ICollection 等)。有趣的是,Microsoft 的 OData 客户端构建器创建的代码将 JSON 作为参数值而不是使用参数别名。但是,OData 路由代码无法找到这样格式的函数调用的控制器。
标签: c# asp.net-web-api odata