C# ASP.NET Odata Web API可组合函数问题

C# ASP.NET Odata Web API可组合函数问题,c#,asp.net,asp.net-web-api,odata,C#,Asp.net,Asp.net Web Api,Odata,我正在Web API OData中构建一个服务层,它公开了一个文件管理API。我对可组合函数有一个问题。考虑下面的场景。可以通过两种方式访问特定文件:通过ID或通过复杂的路径。我最初的设计理念是有两个URL: /File({IdAsGuid}) /Repositories({RepositoryName})/库({libName})/Path({Path})/api.getFileByName(name={fileName}) 这在使用ODataRoute属性时非常有效。下一步是支持使用UR

我正在Web API OData中构建一个服务层,它公开了一个文件管理API。我对可组合函数有一个问题。考虑下面的场景。可以通过两种方式访问特定文件:通过
ID
或通过复杂的
路径
。我最初的设计理念是有两个URL:

  • /File({IdAsGuid})
  • /Repositories({RepositoryName})/库({libName})/Path({Path})/api.getFileByName(name={fileName})
这在使用
ODataRoute
属性时非常有效。下一步是支持使用URL的版本,如:

  • /File({IdAsGuid})/Versions({versionNumber})
  • /Repositories({RepositoryName})/库({libName})/Path({Path})/api.getFileByName(name={fileName})/Versions({versionNumber})
使用
EntitySet
“Versions”作为路径段没有问题,或者是第一个URL。但是,OData拒绝验证函数调用后使用的
EntitySet
。错误:

段“eBesNg.getContentByName”必须是 URI,因为它是以下选项之一:$ref、$batch、$count、$value、, $metadata、命名媒体资源、操作、不可定位 函数、操作导入、不可配置函数导入、 返回类型为void的操作,或导入类型为void的操作 返回类型

经过研究,我意识到该函数的定义如下:

builder.Namespace=“api”;
var function=builder.EntityType().function(“getFileByName”);
函数。参数(“名称”);
function.ReturnsFromEntitySet(“文件”);
并可额外要求:

function.IsComposable=true;
然而,这产生了一个不同的问题。现在,在OData验证期间,我收到一个
NullReferenceException

[NullReferenceException:对象引用未设置为对象的实例。]
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreatePropertySegment(ODataPathSegment previous,IEdmProperty属性,字符串查询比例)+205
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreateNextSegment(字符串 文本)+405
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.ParsePath(ICollection'1 段)+244
Microsoft.OData.Core.UriParser.Parsers.ODataPathFactory.BindPath(ICollection'1 段,段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段/段 Microsoft.OData.Core.UriParser.ODataUriParser.ParsePathImplementation() +205


我错过了什么?无法使用函数进行导航并在OData中继续导航结果吗?

您应该正确设置函数的
EntitySetPath
。即,替换:

function.ReturnsFromEntitySet(“文件”);

function.ReturnsEntityViaEntitySetPath(“bindingParameter/xxx”);
以下是完整的示例:

类路径
{
公共字符串Id{get;set;}
公共文件{get;set;}
}
类文件
{
公共Guid Id{get;set;}
公共ICollection版本{get;set;}
}
类版本
{
公共字符串Id{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var builder=新的ODataConventionModelBuilder();
builder.Namespace=“api”;
builder.EntityType();
var function=builder.EntityType().function(“getFileByName”);
函数。参数(“名称”);
//function.ReturnsFromEntitySet(“文件”);
returnSentityViatentitySetPath(“bindingParameter/File”);
function.IsComposable=true;
builder.EntitySet(“路径”);
builder.EntitySet(“版本”);
var model=builder.GetEdmModel();
string path=“Paths('1')/api.getFileByName(name='sd')/Versions('s')”;
var parser=newodatauriparser(model,newuri(path,UriKind.Relative));
var pa=parser.ParsePath();
控制台写入线(pa);
}
}

您应该正确设置函数的
EntitySetPath
。即,替换:

function.ReturnsFromEntitySet(“文件”);

function.ReturnsEntityViaEntitySetPath(“bindingParameter/xxx”);
以下是完整的示例:

类路径
{
公共字符串Id{get;set;}
公共文件{get;set;}
}
类文件
{
公共Guid Id{get;set;}
公共ICollection版本{get;set;}
}
类版本
{
公共字符串Id{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var builder=新的ODataConventionModelBuilder();
builder.Namespace=“api”;
builder.EntityType();
var function=builder.EntityType().function(“getFileByName”);
函数。参数(“名称”);
//function.ReturnsFromEntitySet(“文件”);
returnSentityViatentitySetPath(“bindingParameter/File”);
function.IsComposable=true;
builder.EntitySet(“路径”);
builder.EntitySet(“版本”);
var model=builder.GetEdmModel();
string path=“Paths('1')/api.getFileByName(name='sd')/Versions('s')”;
var parser=newodatauriparser(model,newuri(path,UriKind.Relative));
var pa=parser.ParsePath();
控制台写入线(pa);
}
}