Как передать несколько параметров в GET ASP.Net Web API?

102

Я использую веб-API.Net MVC4 для (надеюсь) реализации RESTful api. Мне нужно передать несколько параметров в систему и выполнить какое-либо действие, а затем вернуть список объектов в качестве результатов. В частности, я прохожу через две даты и возвращая записи, которые находятся между ними. Я также отслеживаю возвращаемые записи, чтобы последующие вызовы не перерабатывались в системе.

Я рассмотрел несколько подходов:

  • Сериализация параметров в одну строку JSON и выделение ее в API. http://forums.asp.net/t/1807316.aspx/1

  • Передайте параметры в строке запроса.
    Каков наилучший способ передать несколько параметров запроса в restful api?

  • Определение параметров на маршруте: API/контроллер/date1/дата2

  • Использование POST, который по сути позволяет мне передать объект с параметрами.

  • Исследование ODATA, поскольку веб-API (в настоящее время) поддерживает его. Я еще не много сделал с этим, поэтому я не очень хорошо знаком с ним.

Кажется, что правильные методы REST указывают, когда данные тянутся, вы должны использовать GET. Однако GET также должен быть нулевым (не вызывает побочных эффектов), и мне интересно, нарушает ли моя конкретная реализация это, поскольку я отмечаю записи в системе API, поэтому я создаю побочные эффекты.

Это также привело меня к вопросу поддержки переменных параметров. Если список входных параметров изменится, было бы утомительно повторить определение вашего маршрута для выбора 3, если это произойдет очень часто. И что может произойти, если параметры определены во время выполнения...

В любом случае, для моей конкретной реализации, какой выбор (если есть) лучше всего?

Теги:
asp.net-mvc
rest
asp.net-web-api
asp.net-mvc-4

7 ответов

7
Лучший ответ

Что означает эта запись? Если это используется только для ведения журнала, я бы использовал GET и отключил все кэширование, так как вы хотите регистрировать каждый запрос для этих ресурсов. Если эта маркировка записей имеет другую цель, POST - это путь. Пользователь должен знать, что его действия влияют на систему и метод POST является предупреждением.

  • 0
    Под пометкой я имею в виду просто отслеживание того, какие записи обрабатываются и возвращаются, чтобы последующие вызовы не повторяли их. В моем случае я просто делаю вставку в другую таблицу, чтобы отслеживать, какие из них обрабатываются.
  • 0
    Прямо сейчас у меня это реализовано как ПОЧТА в основном по той причине, о которой вы сказали - действия происходят, и потребитель знает о них. Кроме того, это кажется простым и наиболее гибким в отношении передачи различных данных.
Показать ещё 2 комментария
95

Я думаю, что самый простой способ - просто использовать AttributeRouting.

В вашем контроллере очевидно, почему вы хотите это в своем глобальном файле WebApiConfig?

Пример:

    [Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
    public string Get(int paramOne, int paramTwo)
    {
        return "The [Route] with multiple params worked";
    }

Названия {} должны соответствовать вашим параметрам.

Простым образом, теперь у вас есть отдельный GET, который обрабатывает несколько параметров в этом экземпляре.

  • 11
    Это замечательно. Большинство людей рекомендуют настроить маршрут в файле WebApiConfig , но это действительно лучше.
  • 3
    Действительно, мы (большинство людей) рекомендуем иметь централизованную область управления для вашей конфигурации. В случае веб-API (Microsoft или иным способом) централизованные шаблоны для REST являются ключевыми. Маршрутизация атрибутов симпатична, но делает одноразовые исключения слишком заманчивыми.
Показать ещё 10 комментариев
43

Просто добавьте новый маршрут в записи WebApiConfig.

Например, для вызова:

public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..

добавить:

config.Routes.MapHttpRoute(
    name: "GetPagedData",
    routeTemplate: "api/{controller}/{pageNumber}/{pageSize}"
);

Затем добавьте параметры в HTTP-вызов:

GET //<service address>/Api/Data/2/10 
  • 9
    Это, кажется, единственный ответ, который перечисляет все части. Я хотел бы, чтобы кто-то лучше описал, как использовать api/controller?start=date1&end=date2 style URI.
  • 0
    @ Горячий ответ Эндрю Верига хорошо работает с аргументами строки запроса. По сути, вы связываете имена строк запроса со свойствами класса и передаете их в свой метод. Ваш метод будет принимать единственный аргумент класса, помеченный атрибутом [FromUri], и будет иметь аргументы строки запроса в качестве своих свойств.
Показать ещё 1 комментарий
38

Мне просто нужно было выполнить RESTfull api, где мне нужно передать параметры. Я сделал это, передав параметры в строке запроса в том же стиле, как описано в первом примере "api/controller? Start = date1 & end = date2"

В контроллере я использовал подсказку из URL-адреса, разделенного на С#?

// uri: /api/courses
public IEnumerable<Course> Get()
{
    NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    var system = nvc["System"];
    // BL comes here
    return _courses;
}

В моем случае я вызывал WebApi через Ajax, как:

$.ajax({
        url: '/api/DbMetaData',
        type: 'GET',
        data: { system : 'My System',
                searchString: '123' },
        dataType: 'json',
        success: function (data) {
                  $.each(data, function (index, v) {
                  alert(index + ': ' + v.name);
                  });
         },
         statusCode: {
                  404: function () {
                       alert('Failed');
                       }
        }
   });

Надеюсь, это поможет...

  • 2
    Я предполагаю, что вы не используете WebApi, потому что ParameterBinding автоматически сопоставит вашу строку запроса с параметрами вашего метода API ...
  • 1
    Да, лучшим способом было бы использовать и атрибуты, такие как [Route ("api / DbMetaData / {system} / {searchString}")], а затем добавить туда параметры в Get (строка system, string searchString) и затем вызвать с помощью " ... апи / DbMetaData / mysystem / mysearchstring»
Показать ещё 1 комментарий
33

Я нашел отличное решение на http://habrahabr.ru/post/164945/

public class ResourceQuery
{
   public string Param1 { get; set; }
   public int OptionalParam2 { get; set; }
}

public class SampleResourceController : ApiController
{
    public SampleResourceModel Get([FromUri] ResourceQuery query)
    {
        // action
    }
}
  • 5
    Ключом здесь является [FromUri]
  • 2
    Хотя статья на русском языке, @tranceporter прав. «FromUri» выглядит как отличный способ получить параметры из URL. Еще одна статья, которая может быть полезна: asp.net/web-api/overview/formats-and-model-binding/…
Показать ещё 2 комментария
7

Используйте привязку параметров, как описано здесь полностью: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

7

Использование GET или POST ясно объясняется @LukLed. Что касается способов передачи параметров, я бы предложил перейти со вторым подходом (я тоже мало знаю об ODATA).

1. Сериализация параметров в одну строку JSON и выделение ее в API. http://forums.asp.net/t/1807316.aspx/1

Это не дружелюбный к пользователю и оптимизированный для SEO

2. Настройте параметры в строке запроса. Каков наилучший способ передать несколько параметров запроса для спокойного api?

Это обычный предпочтительный подход.

3. Определение параметров на маршруте: api/controller/date1/date2

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

В простом случае я бы предложил URI, как это,

api/controller?start=date1&end=date2

Но мне лично нравится шаблон ниже URI, но в этом случае мы должны написать некоторый код для сопоставления параметров.

api/controller/date1,date2
  • 0
    На самом деле, это были мои объяснения. Я думаю, что LukLed осветил мои теги и ссылку URL.
  • 0
    Что касается SEO, в этом случае это не будет применяться. Этот код будет «сервер-сервер», поэтому мне было бы все равно, обнаружит ли его когда-либо внешний мир. На самом деле, я должен убедиться, что предприняты надлежащие меры безопасности, чтобы избежать произвольного доступа. Мне пришлось выполнить сериализацию JSON для другой части системы (кажется, это ошибка при попытке размещения больших списков объектов в формате POST, поэтому мне пришлось сериализовать в строку), так что в этом случае это не будет большой проблемой. ,
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню