Маршрутизация атрибута для двух действий приводит к «Недопустимому шаблону пути OData» - PullRequest
0 голосов
/ 15 мая 2018

Итак, у меня есть две функции, которые возвращают клиента, который получает два разных параметра.Один - это идентификатор клиента, а другой - его номер.

Мой контроллер:

using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Routing;
using Models;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using System.Web.OData.Extensions;
using Importing;
using Objects;
using Microsoft.OData;

namespace Controllers
{
    public class CustomersController : ODataController
    {
        // GET: CustomerByCNO(5)
        [HttpGet]
        [ODataRoute("CustomerByCNO({key})")]
        [EnableQuery]
        public SingleResult<CustomerDTO> GetCustomerByCNO([FromODataUri]string key)
        {
            Import i = new Import();

            var customer = i.GetCustomer(key).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }

        // GET: Customer(5)
        [HttpGet]
        [ODataRoute("Customer({id})")]
        [EnableQuery]
        public SingleResult<CustomerDTO> Get([FromODataUri]int id)
        {
            Import i = new Import();

            var customer = i.GetCustomer(id).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }
    }
}

Инициализация:

using AutoMapper;
using Models;
using Objects;
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using Microsoft.OData.Edm;

namespace API
{
    public static class WebApiConfig
    {
        public static void ConfigureAPI(HttpConfiguration config)
        {
            config.MapODataServiceRoute(
                routeName: "odata",
                routePrefix: "",
                model: GetEdmModel()
            );

            config.EnsureInitialized();
        }

        private static IEdmModel GetEdmModel()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder
            {
                Namespace = "Controllers",
                ContainerName = "DefaultContainer"
            };
            builder.EntitySet<CustomerDTO>("Customer")
                .EntityType.HasKey(c => c.Id)
                .CollectionProperty(c => c.CustomFields);

            var edmModel = builder.GetEdmModel();
            return edmModel;
        }
    }
}

В то время как вторая функция работает какПредполагается, что первые функции этого не делают, а функция EnsureInitialized () создает исключение InvalidOperationException, в котором говорится, что это недопустимый шаблон пути OData и что ресурс не найден.Как я могу заставить это работать?Не совсем уверен, что мне здесь не хватает.

ОБНОВЛЕНИЕ 1:

Изменение метода контроллера на это:

        [HttpGet]
        [ODataRoute("CustomerByNo(No={no})")]
        public SingleResult<CustomerDTO> CustomerByNo([FromODataUri] int no)
        {
            Import i = new Import();

            var customer = i.GetCustomer(no.ToString()).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }

с помощью этой дополнительной строки в конфигурации:

        builder.Function("CustomerByNo").Returns<SingleResult<CustomerDTO>>().Parameter<int>("No");

Сделано так, чтобы я мог хотя бы получить доступ к функциям.Мне пришлось изменить параметр на int, кажется, он не любит строки?Однако возвращаемое значение не десериализуется и отображается как обычно.Также, если я оставлю строку [EnableQuery] в объявлении метода, вызов завершится сбоем, сказав, что он не знает, как десериализовать, так как он не связан с набором сущностей Customer, как я полагаю.

Однако, пытаясь сделать это таким образом, приводит к исходному сообщению об ошибке, что ресурс не найден:

        builder.EntityType<CustomerDTO>().Collection.Function("CustomerByNo").Returns<SingleResult<CustomerDTO>>().Parameter<int>("No");

1 Ответ

0 голосов
/ 15 мая 2018

Вы должны объявить свои пользовательские функции odata в модели соглашения:

FunctionConfiguration customerByCNOFunction = builder.Function("CustomerByCNO");
customerByCNOFunction.Returns<CustomerDTO>();
customerByCNOFunction.Parameter<string>("key");

Обновление:

Мой первый ответ был для объявления функции, которая возвращает тип, не запрашиваемый в odata.Чтобы включить запрос, функция должна возвращать сущность одататы из набора сущностей:

builder.Function("CustomerByNo").ReturnsFromEntitySet<CustomerDTO>("Customer").Parameter<int>("No")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...