ASP.NET MVC — как создать схему контроллера RESTful?

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

Я экспериментирую с ASP.NET MVC 2. Теперь, исходя из фона веб-форм, я действительно имел дело только с HTTP GET и HTTP POST.

Я пытаюсь понять, как применить GET/PUT/POST/DELETE к соответствующим операциям CRUD в моем репозитории (Найти, Вставить, Обновить, Удалить ).

Скажем, у меня есть один контроллер со следующими методами действий:

[HttpGet] // GET: /Products/{id}
[ActionName("Products")
public ActionResult Get(int id = 0) { ... }

[HttpPut] // PUT: /Products
[ActionName("Products")
public ActionResult Put(Product product) { ... }

[HttpPost] // POST: /Products/{product}
[ActionName("Products")
public ActionResult Post(Product product) { ... }

[HttpDelete] // DELETE: /Products/{product}
[ActionName("Products")
public ActionResult Delete(Product product) { .. }

Пара вопросов по этому поводу - как бы вы назвали/разделили методы действия? Должен ли я проходить через всю модель (продукт) или только идентификатор?

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

На этом этапе я думаю, что у меня будет 3 представления:

  1. «Индекс» — привязка к модели IEnumerable<Product>, список всех продуктов со ссылками «Редактировать», «Подробности» и «Удалить».
  2. "Single" — привязка к одной модели Product, в которой перечислены все сведения о продукте с кнопкой "Обновить".
  3. "Новый" - привязка к одной Product модели, с формой для создания товара, с кнопкой "Создать".

Итак, мой вопрос: как мне указать, что я хочу вызывать определенный метод контроллера с определенной HTTP-командой?

С помощью Html.BeginForm вы можете указать перечисление FormMethod, но оно имеет только GET и POST.

  • Как я могу выполнить команду PUT и DELETE?
  • Нужно ли мне отдельное представление для каждого HTTP-глагола?
  • Если у меня есть ссылка под названием «Удалить», могу ли я вызвать команду HTTP DELETE для своего контроллера или ее нужно перенаправить на новый вид с помощью действия формы «Удалить»?

Или, во-первых, это глупый / излишний дизайн, я должен просто придерживаться «GET» и «POST»?

Я (довольно) новичок в этом стиле веб-разработки (REST), поэтому, пожалуйста, будьте добры. :)

ОБНОВЛЕНИЕ

Итак, я наткнулся на эта интересная статья Стивена Вальтера, посвященная именно этой теме.

Он указывает, что HTML-форма поддерживает только GET и POST (поскольку я новичок в веб-разработке в стиле REST, я даже не знал об этом, за что мне частично стыдно).

По-видимому, единственный способ вызвать действие контроллера с помощью PUT/DELETE — это сделать это с помощью AJAX. Шутки в сторону?

Итак, что мне делать здесь, следует ли мне придерживаться GET/POST или мне следует создать файл JavaScript, который обертывает базовый код XmlHttpRequest за красивой функцией?

В какую сторону склоняются разработчики ASP.NET MVC? Наверняка кто-то задавал себе этот же вопрос.


person RPM1984    schedule 24.09.2010    source источник
comment
Незнание того, что GET и POST являются единственными широко поддерживаемыми формами HTML, очень распространено, поэтому не беспокойтесь, что вы этого не знали :)   -  person eglasius    schedule 24.09.2010


Ответы (3)


Причина, по которой вы в основном знакомы с GET и POST, заключается в том, что обычный старый браузер может только GET или POST URL, особенно при отправке формы.

Настраивая свои контроллеры таким образом, вы смотрите на нечто большее, чем REST API, по сравнению с веб-сайтом, по крайней мере, по духу.

И да, вы правы в том, что только запросы AJAX могут явно задавать свои методы запроса, поэтому вы можете идти, если будете выполнять такие действия, как удаление продуктов через AJAX (в этом случае я бы предложил только передавать идентификатор, поскольку он намного легче, чем сериализация всего продукта, и у вас, вероятно, будет легкий доступ к идентификатору в вашей разметке).

Вот в чем дело. Если вы создаете современное веб-приложение, вы, вероятно, используете AJAX, и, не будучи слишком догматичным, вы должны ожидать, что у ваших пользователей будет JavaScript. Если вы хотите выполнить CRUD без AJAX, вы всегда можете POST продукта или использовать GET для метода удаления с идентификатором в URL-адресе (предупреждение об этом, убедитесь, что метод Delete защищен авторизацией, иначе веб-сканер с удовольствием использует ваш GET и удалите все ваши данные...)

Если вы не хотите создавать REST API, не беспокойтесь о том, что вы не используете DELETE (просто используйте GET с идентификатором в URL-адресе) или не используете PUT (просто используйте POST с продуктом). сущность в теле POST).

REST — отличный стиль для создания API (без уровня представления, данные отправляются в необработанном формате клиентам, которые их потребляют, это может быть телефон, веб-сайт и т. д.) через HTTP. HTTP отлично подходит для создания веб-страниц. Используйте то, что вам нужно для того, для чего вам это нужно.

Если вы хотите создать REST API, который будет использоваться как другими людьми, так и вашим веб-сайтом, сделайте это, и просто заставьте методы действия контроллера вашего сайта напрямую вызывать ваши методы API. Я делаю это все время. Используйте веб-клиент, например Hammock, чтобы вам было проще.

person Daniel Crenna    schedule 24.09.2010
comment
+1 за а) хороший ответ и б) кто-то наконец ответил, хе-хе. единственный идентификатор точки: я бы предпочел УДАЛИТЬ с помощью POST, а не GET. Принципы REST диктуют, что GET должен выполняться снова и снова без изменения состояния. Однако на данном этапе я, вероятно, склоняюсь к AJAX, потому что на веб-сайте его все равно будет много. Ценю ваш ответ. - person RPM1984; 24.09.2010
comment
@ RPM1984 RPM1984 вы правы, DELETE нужно выполнять с помощью POST, а не GET. - person eglasius; 24.09.2010
comment
Вы не должны делать GET для НИЧЕГО, что изменяет данные. GET — это просто поиск. Если ваше действие включает в себя C, U или D (создание, обновление или удаление), вам следует вызывать с помощью POST. Слишком много шансов на повреждение данных, если все, что нужно, это ПОЛУЧИТЬ, чтобы что-то изменить. - person andymeadows; 24.09.2010
comment
@eglasius, @andymeadows - согласен и согласен. знак равно - person RPM1984; 24.09.2010
comment
Я понимаю идемпотентность, как вы упомянули, но GET и DELETE, кроме этой детали спецификации, идентичны. DELETE также должен быть идемпотентным. Людей иногда смущает разница между идемпотентностью и неизменяющимся состоянием. Я имею в виду, что первый GET может удалить объект, следующий GET для того же URL-адреса должен вернуть 404 или аналогичный. Вот почему я сказал защитить свой GET авторизацией. То же самое относится и к DELETE. Я не вижу здесь реальных аргументов в пользу того, чтобы предпочесть POST GET, если GET защищен от веб-сканирования. DELETE также основан на URL-адресе, поэтому он также может быть поврежден. - person Daniel Crenna; 25.09.2010
comment
Кроме того, проверьте это: indempotence - stackoverflow.com/questions/741192/ ... Я не буду тратить слишком много времени на защиту GET здесь, так как почему бы не использовать POST и избежать возможности человеческой ошибки, но это не так плохо, как утверждает большинство людей. - person Daniel Crenna; 25.09.2010

Лично я придерживаюсь как можно более простых полных запросов вместо того, чтобы использовать AJAX повсюду. Я использую ajax, но в определенных местах, где он улучшает работу (и я использую прогрессивный подход javascript).

Из-за вышеизложенного я всегда использую GET и POST.

Что касается именования, для тех, которые я бы сделал: Получить, Обновить, Создать, Удалить, что делает его довольно ясным. На самом деле я использую больше как имя действия, которое связано с тем, что делает операция, но для простых вещей они работают нормально.

person eglasius    schedule 24.09.2010
comment
Спасибо за ответ. Я согласен с тобой. На данном этапе я просто занимаюсь исследованиями и разработками, поэтому я не собираюсь выбирать между AJAX и GET&POST. Я согласен, решение об AJAX следует принимать на основе UX, а не пытаться придерживаться семантики HTTP. - person RPM1984; 24.09.2010

Метод HtmlHelper.HttpMethodOverride (Система.Web.Mvc)

Как насчет этого?

person takepara    schedule 24.09.2010
comment
Хотите уточнить? (да, я прочитал страницу MSDN). Вы использовали это в MVC? Как? В любом случае, теперь, когда я обнаружил, что формы поддерживают только GET/POST (по крайней мере, до HTML5), я не понимаю, как это будет работать. - person RPM1984; 24.09.2010
comment
‹%= Html.HttpMethodOverride(HttpVerbs.Put) %› ‹%= Html.HttpMethodOverride(HttpVerbs.Delete) %› - person takepara; 24.09.2010
comment
чувак, во-первых, не пиши код в комментарии - отредактируй свой ответ и помести его туда. Во-вторых, это не разработка или объяснение того, как этот код может работать (о чем этот вопрос). Тем не менее, я проведу собственное исследование этого метода. - person RPM1984; 25.09.2010