Почему эти два действия считаются неоднозначными, несмотря на разные параметры? - PullRequest
10 голосов
/ 13 июля 2011

Текущий запрос на действие «Индекс» для типа контроллера «UsersController» неоднозначен между следующими методами действия: System.Web.Mvc.ActionResult PostUser (Models.SimpleUser) для типа Controllers.UsersController System.Web.Mvc.ActionResult PostUser (Int32, Models.SimpleUser) для типа Controllers.UsersController

Происходит, когда я пытаюсь POST website.com/users/ со значениями формы.

Когда нет идентификатора (website.com/users/), я хочу, чтобы он создал нового пользователя, когда есть идентификатор (например, / users / 51), я хочу, чтобы он обновил этого пользователя, так как я могу заставить это сказать разницу между этими двумя действиями?

Вот два действия:

    [HttpPost]
    [ActionName("Index")]
    public ActionResult PostUser(SimpleUser u)
    {

        return Content("User to be created...");
    }

    [HttpPost]
    [ActionName("Index")]
    public ActionResult PostUser(int id, SimpleUser u)
    {

        return Content("User to be updated...");
    }

Вот MapRoute:

    routes.MapRoute(
        "Users",
        "users/{id}",
        new { controller = "Users", action = "Index" }
    );

Ответы [ 3 ]

8 голосов
/ 13 июля 2011

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

У вас может быть тот же URL-адрес, но было бы полезно назвать ваши действия по-другому, а затем применить несколько новых маршрутов.

[HttpPost]
public ActionResult Create(SimpleUser u)
{
    return Content("User to be created...");
}

[HttpPost]
public ActionResult Edit(int id, SimpleUser u)
{
    return Content("User to be updated...");
}

Изатем в вашей маршрутизации попробуйте

routes.MapRoute(
    "UserEdit",
    "users/{id}",
    new { controller = "Users", action = "Edit", 
        httpMethod = new HttpMethodConstraint("POST") });

routes.MapRoute(
    "UserCreate",
    "users",
    new { controller = "Users", action = "Create", 
        httpMethod = new HttpMethodConstraint("POST") });

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

0 голосов
/ 13 июля 2011

Вы должны устранить неоднозначность своих методов, имея два разных имени действия.

Чтобы использовать RESTful API, вы можете создать собственный класс RouteHandler, который изменит маршрутизацию в зависимости от того, присутствует ли значение {id}. Класс RouteHandler прост:

using System.Web.Mvc;
using System.Web.Routing;

  public class MyRouteHandler : IRouteHandler
  {
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
      var routeData = requestContext.RouteData;
      if (routeData.Values("id").ToString() == "0" /* our default invalid value */ )
      {
        var action = routeData.Values("action");
        routeData.Values("action") = action + "Add";
      }
      var handler = new MvcHandler(requestContext);
      return handler;
    }
  }

Затем измените RegisterRoutes() в Global.asax.cs следующим образом:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        AreaRegistration.RegisterAllAreas();

        routes.Add("Default", new Route("{controller}/{action}/{id}",
            new RouteValueDictionary(
                new { controller = "Home", 
                      action = "Index", 
                      id = "0" /* our default invalid value */ }),
            new MyRouteHandler()));
    }

Наконец, измените атрибут ActionName для вашего метода Add на «IndexAdd». Когда запрос приходит без идентификатора, будет предоставлено недопустимое значение по умолчанию, которое предупредит вашего RouteHandler о смене метода на ваш метод «Добавить».

counsellorben

0 голосов
/ 13 июля 2011

Было бы лучше, если бы вы решили использовать действия «Создать» и «Редактировать» для достижения желаемого.Обычно индекс может быть использован для перечисления всех пользователей (в вашем случае).Что касается проблемы, с которой вы столкнулись, то она возникает из-за того, что нет маршрута, который не принимает идентификатор в качестве параметра.

...