ASP.NET MVC: использование GET и POST в одном методе - PullRequest
1 голос
/ 18 ноября 2009

Вот сценарий: когда новый пользователь регистрируется на нашем веб-сайте, мы хотим отправить электронное письмо, чтобы убедиться, что пользователь владеет адресом электронной почты. В письме есть ссылка на страницу, которая будет выполнять проверку, примерно так:

http://www.mysite.com/account/verify/token

Метод проверки выглядит следующим образом:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Verify(Nullable<Guid> id)
{
    // tries to get the user based on the verification code
    if (ValidId(id))
    {
        // if the id is correct, update user data in the model and redirect
        return RedirectToAction("Index", "Dashboard");
    }
    else
    {
        // redirects the user to the verify view
        return View("Verify");
    }
}  

Представление «Подтвердить» - это просто текстовое поле с кнопкой, поэтому пользователь может ввести проверочный код вручную (пользователь может перейти на эту страницу с сайта и может предпочесть просто скопировать и вставить код). Когда пользователь нажимает кнопку, я хочу сделать то же самое, что и мой метод GET ; так что я получил что-то вроде этого:

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult Verify(Nullable<Guid> id) { ... }

У меня есть пара проблем с этим кодом (который работает, но ...):

  • Можно ли использовать метод GET и POST? Или есть лучший способ справиться с этим сценарием?
  • Я изменяю данные в методе GET (если идентификатор правильный, я обновляю данные пользователя, чтобы отразить, что они проверены), и это большое НЕТ НЕТ ... тем не менее, я хочу, чтобы пользователь просто мог нажмите на ссылку и проверьте токен. Есть ли лучший способ добиться этого?

Спасибо

Ответы [ 4 ]

1 голос
/ 18 ноября 2009

Лично я не стал бы беспокоиться об атрибуте AcceptVerbs. (** См. Примечание ниже). Затем вы можете объединить это в одно действие, которое может реагировать при необходимости. (Ниже показан некоторый непроверенный код.) Причина, по которой я добавляю ответ вместо простого комментария, состоит в том, что я хотел бы рекомендовать вам добавить еще одну ветвь в свою логику для обработки ошибочного кода (т. Е. Для представления сообщения об ошибке) .

public ActionResult Verify(Nullable<Guid> id)
{
    if (!id.HasValue)
    {
        // nothing was submitted
        ViewData["message"] = "Please enter your ID and press Submit";
        return View("Verify");
    }
    if (!ValidId(id))
    {
        // something was submitted, but wasn't valid
        ViewData["message"] = "ID is invalid or incomplete. Pleaes check your speeling";
        return View("Verify");
    }
    // must be valid
    return RedirectToAction("Index", "Dashboard");

}

Вы тогда, конечно, могли бы отобразить <%=ViewData["message"]%> в своем окне проверки. Это, конечно, простой пример.

** ОК, вот мое примечание RE: не беспокоиться с атрибутом AcceptVerbs:
В вашем сценарии вы также можете просто выбрать метод формы GET вместо POST. Поскольку вы уже «предпринимаете действия» и изменяете состояние удобной ссылки, по которой нажимают пользователи, я не вижу никакой разницы. Я просто упомянул это, чтобы быть тщательным, хотя я лично выбрал бы мою предыдущую рекомендацию.

Удачи!

1 голос
/ 18 ноября 2009

Я изменяю данные методом GET ... и это большое НЕТ НЕТ

Я бы не сказал, что это всегда большое нет, нет. HTTP говорит, что метод GET "СЛЕДУЕТ" быть "безопасным", то есть он НЕ ДОЛЖЕН иметь никакого эффекта, кроме поиска информации. В этом случае я думаю, что разумно расширить определение «безопасный», чтобы оно означало, что оно не имеет никаких вредных побочных эффектов, и, действительно, единственный возможный побочный эффект, который может иметь ваша ссылка для проверки, является желательным.

Другим свойством, которое должен иметь метод GET, является идемпотентность: если пользователь нажимает ссылку для проверки несколько раз, это аналогично тому, как если бы он щелкнул по ней только один раз. Надеюсь, у вас есть это свойство, поскольку ссылка для проверки генерируется с помощью одноразового кода.

0 голосов
/ 18 ноября 2009

если вас это беспокоит, то что с этим не так?

        [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Verify()
    {
        return View("Verify");
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Verify(Guid? id)
    {
        if (ValidId(id))
        {
            return RedirectToAction("Index", "Dashboard");
        }

        return View("Verify");
    }
0 голосов
/ 18 ноября 2009

Я должен сказать, что редко можно встретить кого-то, настолько озабоченного использованием правильного HTTP-глагола. Я не верю, что первоначальная цель спецификации HTTP заключалась в том, чтобы ограничить все отправленные данные редактирования в POST, а все поиски в GET. Я думаю, что ты делаешь просто отлично.

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