尽管参数不同,为什么这两个操作被认为是不明确的?

发布于 2024-11-19 15:06:01 字数 945 浏览 2 评论 0原文

当前对控制器类型“UsersController”上的操作“Index”的请求在以下操作方法之间不明确: Controllers.UsersController 类型上的 System.Web.Mvc.ActionResult PostUser(Models.SimpleUser) System.Web.Mvc.ActionResult PostUser(Int32, Models.SimpleUser) on type Controllers.UsersController

当我尝试使用表单值 POST website.com/users/ 时,会发生

当没有ID(website.com/users/)时,我希望它创建一个新用户,当有ID(例如/users/51)时,我希望它更新该用户,那么我怎样才能让它告诉这两个Action的区别?

这是两个操作:

    [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" }
    );

The current request for action 'Index' on controller type 'UsersController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult PostUser(Models.SimpleUser) on type Controllers.UsersController
System.Web.Mvc.ActionResult PostUser(Int32, Models.SimpleUser) on type Controllers.UsersController

Is happening when I try to POST website.com/users/ with form values.

When there is NO ID (website.com/users/) I want it to create a new user, when there IS an ID (/users/51 for example) I want it to update that user, so how can I make it tell the difference between these two Actions?

Here are the two actions:

    [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...");
    }

Here is the MapRoute:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谢绝鈎搭 2024-11-26 15:06:01

主要问题是两个操作方法之间存在一些模糊性,因为模型绑定无助于确定路由配置。您当前的路由仅指向索引方法。

您仍然可以使用相同的 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 方法添加一些路由。比如列表什么的。

The main problem is there is some ambiguity between your two action methods, as model binding doesn't help decern the routing configuration. Your current routing simply points to index method.

You can still have the same URL, but it would be helpful to name your actions differently and then apply some new routes.

[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...");
}

And then in your routing try

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") });

The routes will be constrained to POST events only, which means you can still add some routing for your GET methods on the same route. Such as for a list or something.

明明#如月 2024-11-26 15:06:01

您必须通过使用两个不同的操作名称来消除方法的歧义。

要拥有 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;
    }
  }

接下来,修改 Global.asax.cs 中的 RegisterRoutes(),如下所示:

    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()));
    }

最后,将 Add 方法的 ActionName 属性更改为“IndexAdd”。当请求没有 id 时,将提供默认的无效值,这将提醒您的 RouteHandler 将方法更改为“Add”方法。

辅导员本

You must disambiguate your methods by having two different action names.

What you can do to have a RESTful API is to create your own RouteHandler class which will change the routing, dependent on whether or not the {id} value is present. The RouteHandler class is simple:

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;
    }
  }

Next, modify RegisterRoutes() in Global.asax.cs as follows:

    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()));
    }

Finally, change the ActionName attribute for your Add method to "IndexAdd". When the request comes in without an id, the default invalid value will be supplied, which will alert your RouteHandler to change the method to your "Add" method.

counsellorben

忘年祭陌 2024-11-26 15:06:01

如果您考虑使用“创建”和“编辑”操作来实现您想要的效果,那就更好了。一般来说,索引可用于列出所有用户(在您的情况下)。
关于您面临的问题,它的出现是因为没有任何路由不采用任何 id 作为参数。

It would be better if you consider using Create and Edit actions to achieve what you want. Generally index can be used to list all the users(in your case).
About the problem you are facing, it is arising because there is no route which does not take any id as parameter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文