【问题标题】:ASP.NET Odata Web API Composable function issueASP.NET Odata Web API 可组合函数问题
【发布时间】:2015-08-24 11:45:58
【问题描述】:

我正在 Web API OData 中构建一个服务层,它公开了一个文件管理 API。我对可组合函数有疑问。考虑以下场景。可以通过两种方式访问​​特定文件:通过ID 或通过复杂的Path。我最初的设计理念是有两个 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");

并且可能还需要:

function.IsComposable = true;

但是,这产生了一个不同的问题。现在,在 OData 验证期间,我收到了 NullReferenceException

[NullReferenceException:对象引用未设置为对象的实例。]
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreatePropertySegment(ODataPathSegment 上一个,IEdmProperty 属性,字符串 queryPortion) +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 段,ODataUriParserConfiguration 配置)+96
Microsoft.OData.Core.UriParser.ODataUriParser.ParsePathImplementation() +205

我错过了什么?是否不能使用导航功能继续导航 OData 中的结果?

【问题讨论】:

    标签: c# asp.net asp.net-web-api odata


    【解决方案1】:

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

    function.ReturnsFromEntitySet<File>("Files");
    

    function.ReturnsEntityViaEntitySetPath<File>("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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      相关资源
      最近更新 更多