我在Web API Odata中构建服务层,它暴露了文件管理API,我遇到了可组合函数的问题。让我们考虑以下场景。可以通过两种方式访问特定文件:通过ID或复杂路径。我最初的设计理念是拥有2个URL:
/File({IdAsGuid})
/Repositories({RepositoryName})/Libraries({libName})/Path({path})/api.getFileByName(name={fileName})
使用OdataRoute属性可以很好地工作。 下一步是支持版本,它们将使用URL,如:
/File({IdAsGuid})/Versions({versionNumber})
/Repositories({RepositoryName})/Libraries({libName})/Path({path})/api.getFileByName(name={fileName})/Versions({versionNumber})
使用EntitySet"版本"作为路径段没有问题或第一个URL。但Odata拒绝验证函数调用后使用的EntitySet。错误:
经过一些研究,我意识到这个功能定义如下:细分' eBesNg.getContentByName'必须是最后一段 URI,因为它是以下之一:$ ref,$ batch,$ count,$ value, $ metadata,命名媒体资源,动作,不可分解 功能,动作导入,不可分解的功能导入, void返回类型的操作,或带void的操作导入 返回类型。
builder.Namespace = "api";
var function = builder.EntityType<Path>().Function("getFileByName");
function.Parameter<string>("name");
function.ReturnsFromEntitySet<File>("Files");
可能需要additonaly:
function.IsComposable = true;
然而,这产生了一个不同的问题。现在在Odata验证期间,我收到Null Exception:
[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreatePropertySegment(ODataPathSegment previous,IEdmProperty属性,String queryPortion)+205
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreateNextSegment(字符串 文字)+405
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.ParsePath(ICollection的1 segments) +244
1 segment,ODataUriParserConfiguration配置)+96
Microsoft.OData.Core.UriParser.Parsers.ODataPathFactory.BindPath(ICollection
Microsoft.OData.Core.UriParser.ODataUriParser.ParsePathImplementation() 205
我错过了什么?是不是可以将函数用作导航并继续在Odata中导航结果?
答案 0 :(得分:0)
您应该正确设置函数的EntitySetPath。那就是取代
function.ReturnsFromEntitySet( “文件”);
与
function.ReturnsEntityViaEntitySetPath( “bindingParameter / XXX”);
以下是完整的示例:
class Path
{
public string Id { get; set; }
public File File { get; set; }
}
class File
{
public Guid Id { get; set; }
public ICollection<Version> Versions { get; set; }
}
class Version
{
public string Id { get; set; }
}
class Program
{
static void Main(string[] args)
{
var builder = new ODataConventionModelBuilder();
builder.Namespace = "api";
builder.EntityType<File>();
var function = builder.EntityType<Path>().Function("getFileByName");
function.Parameter<string>("name");
//function.ReturnsFromEntitySet<File>("Files");
function.ReturnsEntityViaEntitySetPath<File>("bindingParameter/File");
function.IsComposable = true;
builder.EntitySet<Path>("Paths");
builder.EntitySet<Version>("Versions");
var model = builder.GetEdmModel();
string path = "Paths('1')/api.getFileByName(name='sd')/Versions('s')";
var parser = new ODataUriParser(model, new Uri(path, UriKind.Relative));
var pa = parser.ParsePath();
Console.WriteLine(pa);
}
}