2015-06-09 3 views
1

Я строю уровень обслуживания в веб-API Odata, который предоставляет API управления файлами, и у меня есть проблема с составными функциями. Давайте рассмотрим следующий сценарий. К частным файлам можно обращаться двумя способами: через идентификатор или сложный Путь. Моя первоначальная концепция дизайна была иметь 2 URLS:ASP.NET Odata Web API Составляемая функция проблема

/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, используемый после вызова функции. Ошибка:

The segment 'eBesNg.getContentByName' must be the last segment in the URI because it is one of the following: $ref, $batch, $count, $value, $metadata, a named media resource, an action, a noncomposable function, an action import, a noncomposable function import, an operation with void return type, or an operation import with void return type.

После некоторых исследований я понял, что функция определяется следующим образом:

builder.Namespace = "api"; 
var function = builder.EntityType<Path>().Function("getFileByName"); 
function.Parameter<string>("name"); 
function.ReturnsFromEntitySet<File>("Files"); 

может потребовать additonaly:

function.IsComposable = true; 

Однако это создало другой вопрос. Теперь во время проверки Одаты я получаю Null Exception:

[NullReferenceException: Object reference not set to an instance of an object.] 

Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreatePropertySegment(ODataPathSegment previous, IEdmProperty property, String queryPortion) +205
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreateNextSegment(String text) +405
Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.ParsePath(ICollection 1 segments) +244
Microsoft.OData.Core.UriParser.Parsers.ODataPathFactory.BindPath(ICollection
1 segments, ODataUriParserConfiguration configuration) +96
Microsoft.OData.Core.UriParser.ODataUriParser.ParsePathImplementation() +205

Что мне не хватает? Невозможно ли использовать функции в качестве навигации и продолжать перемещаться по результатам в Odata?

ответ

0

Вы должны правильно установить EntitySetPath своей функции. То есть для замены

function.ReturnsFromEntitySet («Файлы»);

с

function.ReturnsEntityViaEntitySetPath ("bindingParameter/ххх");

Вот полный пример:

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); 
    } 
} 
Смежные вопросы