Контроллеры RESTful с разными методами Http, но с одинаковыми параметрами - PullRequest
4 голосов
/ 09 февраля 2011

Допустим, у меня есть контроллер, который обрабатывает сценарий CRUD для «Дома». Get будет выглядеть примерно так:

    [HttpGet]
    public ActionResult Index(int? homeId)
    {
        Home home = homeRepo.GetHome(homeId.Value);

        return Json(home, JsonRequestBehavior.AllowGet);
    }

Пока все хорошо. Затем я добавляю сообщение для добавления новых.

    [HttpPost]
    public ActionResult Index(Home home)
    {
        //add the new home to the db

        return Json(new { success = true });
    }

Высокий. Но когда я использую ту же схему для обработки пут (обновление существующего дома) ...

    [HttpPut]
    public ActionResult Index(Home home)
    {
        //update existing home in the db

        return Json(new { success = true });
    }

Мы столкнулись с проблемой. Сигнатуры методов для Post и Put идентичны, что, конечно, в C # не нравится. Я мог бы попробовать несколько вещей, таких как добавление фиктивных параметров в сигнатуру или изменение имен методов для непосредственного отражения CRUD. Это, однако, нахально или нежелательно.

Как лучше всего сохранять здесь контроллеры в стиле RESTful CRUD?

Ответы [ 2 ]

12 голосов
/ 09 февраля 2011

Это лучшее из известных мне решений:

[HttpPut]
[ActionName("Index")]
public ActionResult IndexPut(Home home) 
{
     ...
}

В основном ActionNameAttribute был создан для работы с этими сценариями.

0 голосов
/ 09 февраля 2011

HttpPut и HttpDeletes ограничены некоторыми брандмауэрами, поэтому иногда используются просто HttpPost и HttpGet.Если идентификатор записи передается (или некоторым другим критериям), вы знаете, что это обновление.Конечно, это вы должны определить, httpput может нормально работать для вас, это всего лишь предупреждение, обычно это не имеет большого значения.

Любой используемый метод - остерегайтесь пользователей, пытающихся ввести ложные идентификаторы на страницу, чтобы принудительно обновить записи, к которым у них нет доступа.Я могу обойти эту проблему, хэшируя в этом случае home.HomeId в представлении, когда мы отображаем его

ViewData["IdCheck"] = Encryption.ComputeHash(home.HomeId.ToString());

в вашем представлении:

    <%: Html.Hidden("IdCheck", ViewData["IdCheck"]) %>

в вашем методе HttpPost или HttpPut (в зависимости от того, чтовыполняет обновление)

 if (Encryption.ComputeHash(home.HomeId.ToString()) != (string)Request.Form["IdCheck"])
 {
       throw new Exception("Hashes do not match");
}

Опять же - такая же проблема безопасности существует независимо от того, какой метод вы используете для обновления, если доверяете данным формы.

...