WebAPI: десериализация параметра URI для параметра действия poco - PullRequest
0 голосов
/ 21 марта 2012

Учитывая определение маршрута как это:

        routes.MapHttpRoute(
            name: "Categories",
            routeTemplate: "{controller}/Categories/{entity}/{property}",
            defaults: new { action = "Categories", entity = RouteParameter.Optional, property = "Name" }
        );

И действия контроллера объявлены так:

public IEnumerable<Category> Categories(string property);
public IEnumerable<Category> Categories(string entity, string property);

Цель заключается в том, чтобы контроллер представлял конкретную сущность и мог объединять другие сущности. Возвращенные категории содержат сгруппированные и количество свойств. Поэтому, если контроллером является UserController, а пользовательский объект имеет свойство Name, вы можете вызвать User/Categories/Name и получить результат, показывающий разные имена и сколько из них имеют каждое имя.

Если, однако, у Пользователя также есть объект Address, и у него есть ZipCode, я мог бы позвонить User/Categories/Address/ZipCode и ожидать результата, показывающего, сколько пользователей живут с какими ZipCodes.

Проблема здесь в том, что параметр string entity имеет тип string, а не тип Type, поэтому я должен испачкать действие с помощью кода, чтобы преобразовать его в экземпляр Type, представляющий сущность, и бросить, если это неверная строка.

Я хотел бы вместо этого объявить мое второе действие следующим образом:

public IEnumerable<Category> Categories(Type entity, string property);

Но тогда мне нужно десериализовать строку с помощью специального десериализатора. У меня уже есть собственные десериализаторы ака MediaTypeFormatters для вещей, поступающих из тела контента. Моя проблема здесь в том, что в этом случае источником является параметр URI, а не тело контента.

Что приводит к моим вопросам:

  1. Будет ли MediaTypeFormatter также работать для параметров URI?
  2. Если нет, какую конструкцию я должен реализовать и подключить, как достичь того, чего я хочу?

1 Ответ

3 голосов
/ 22 марта 2012

Пара вещей:

  1. Пользователь / Категории / Имя не будут сопоставлять «Имя» с {свойством}, оно будет сопоставлять «Имя» с {сущностью}.Маршруты соответствуют «жадно» слева направо.

  2. Вместо строки для объекта вы можете использовать enum

    public enum EntityType
    {
        Address,
        Department
    }
    
    public class UserController : ApiController
    {
        public IEnumerable<Category> Categories(EntityType entity, string property)
        {
        }
    }
    

    Вам все еще понадобится кодчто-то сделать с типом сущности, но это кажется более безопасным, чем позволить клиенту отправлять вам случайные имена типов CLR?И тогда привязка модели проверит сегмент {entity} в URI.Поэтому, если клиент запрашивает User / Categories / FavoriteBeer, он получит 400, Bad Request.

  3. Форматеры медиа-типа специально предназначены для сериализации / десериализации тела сообщения.(Форматтеры преобразуются в типы мультимедиа, а типы мультимедиа описывают тело объекта.)

    Средство форматирования мультимедиа имеет доступ к URI запроса через объект FormatterContext, но это не поможет в этом сценарии,потому что запрос GET без тела сообщения не вызовет средство форматирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...