表单未命中控制器

时间:2019-05-17 07:17:22

标签: c# asp.net-mvc razor routes

编辑了问题,因为我发现问题不在剃须刀内,而是在路线上

我有一个非常简单的登录表单,但是以某种方式,当用户按下Login时,页面进入Error404,并且由于某种原因它根本没有达到控制器的断点。

   @using (Html.BeginRouteForm("MyCustomRoute", new { controller = "login", action = "verify", FormMethod.Post }))
                 {
                <fieldset class="clearfix">
                    <p><span style="float:none;color:black; font-size:20pt;"></span></p>
                    <p><span style="float:none;color:black; font-size:20pt;"></span></p>
                    <p><span class="fa fa-user"></span>@Html.TextBoxFor(m => m.UserName, new { @class = "form-control", placeholder = "Username", onkeydown = "convertTabtoEnter(this, event)", autofocus = "" })</p> <!-- JS because of IE support; better: placeholder="Username" -->
                    <p>
                        <span class="fa fa-lock"></span>@Html.PasswordFor(m => m.Password, new { @class = "form-control", placeholder = "Password", onkeyup = "convertTabtoEnter()" })
                    </p> <!-- JS because of IE support; better: placeholder="Password" -->

                    <div>
                        <span style="width:48%; text-align:left;  display: inline-block;">
                            <a class="small-text" href="#">
                                @*Forgot
                    password?*@
                            </a>
                        </span>
                        <span style="width:50%; text-align:right;  display: inline-block;"><input type="submit" value="Sign In"></span>
                    </div>
                </fieldset>
                <div class="clearfix"></div>
                }    

在我的登录控制器中,我有一个简单的ActionResult,名为“ Verify”(带有2个参数)。

    [RoutePrefix("Login")]

public class LoginController : Controller
{
    // GET: Login
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    [Route("Verify")] //Matches GET login/verify

    public ActionResult Verify(string username, string password)
    {...}

我到底在做什么错?并不是说这是火箭科学。

Edit2: 我注意到,无论何时将RouteConfig.cs更改回默认值,它都可以正常工作。因此,问题不在于表单标签之内,而在于路由之内。 因此,我一直在尝试添加自定义路由,以便使用以下示例进行此操作:Using Html.BeginForm() with custom routes

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

            routes.MapRoute(
                name: "TrailersOverview",
                url: "{TrailersOverview}/{action}/{vendid}",
                defaults: new { controller = "TrailersOverview", action = "Index", vendId = UrlParameter.Optional }
            );

             routes.MapRoute(
                "MyCustomRoute", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "login", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

            routes.MapRoute(
                name: "Default",
                url: "{*anything}",
                defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

当我删除路由而只是将所有内容恢复为默认值时,控制器就会受到攻击。不幸的是,我在其余的应用程序中确实需要这些路由:(

4 个答案:

答案 0 :(得分:5)

似乎有几件事是错误的:

  • 您的控制器在路由配置中丢失。
  • 动作和控制器名称顺序错误。

RouteConfig:

默认路由如下:

Interpolation

表格:

如果要使用标签助手,则必须从以下位置更改代码:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}/",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

收件人:

<form action="@Url.Action("Login", "Verify")" method="post">

看看here

答案 1 :(得分:1)

 @using (Html.BeginForm("Verify", "YourControllerName", FormMethod.Post))
{ your form here // }

如果可以,请尝试一下!

在输入字段中再添加一个名称属性,该属性应类似于模型中的属性名称,例如

@Html.TextBoxFor(m => m.UserName, new { @class = "form-control", id="username", name="USERNAME"})

这个USERNAME应该在您的模型中,例如:

Public class yourModel{Public string USERNAME{get;set;}}

然后在“操作方法”中使用模型对象来获取数据。

答案 2 :(得分:1)

您的自定义路线(上述RegisterRoutes代码中的第二条路线)似乎不正确...根据您上面的说明,它可能是/应该是这样的:

routes.MapRoute(
    "MyCustomRoute", // Route name
    "Login/Verify", // (No parameters needed)
    new { controller = "Login", action = "Verify" } // Parameter defaults
);

通过此设置,将剃刀代码的第一行更改为:

@using (Html.BeginRouteForm("MyCustomRoute", FormMethod.Post }))
{
    <fieldset class="clearfix">
    ...
}

使用Html.BeginRouteForm将自动使用您的自定义路由中指定的默认值;无需在Razor中添加默认值。使用FormMethod.Post作为第二个参数会将您的表单方法呈现为POST

编辑: 让我们解决您的一般路线问题。您正在尝试使用属性路由,此处对此进行了很好的描述:https://www.dotnettricks.com/learn/mvc/understanding-attribute-routing-in-aspnet-mvc。我认为这里没有必要。

首先,像下面这样修复默认路由(RegisterRoutes代码中的最后一条路由):

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    // Change the 'controller' and 'action' parameters here to point to the Main page in your application.

您的默认路由非常重要,应将其配置为所有请求的简单组合,以便将任何请求简单地映射到Controller / Action组合。我怀疑您遇到了问题,因为您的默认路线已更改。

接下来,在登录控制器中注释掉RouteRoutePrefix属性。如果正确使用'RegisterRoutes',则几乎不需要[Route("Verify")]指令。< / p>

// [RoutePrefix("Login")]
public class LoginController : Controller
{
    // GET: Login
    public ActionResult Index()
    {
        return View();
    }
    [HttpPost]
    // [Route("Verify")] //Matches GET login/verify
    public ActionResult Verify(string username, string password)
    {...}
}

现在默认路由已正确设置,URL'/ Login'应该带您进入登录屏幕,因为默认操作是“索引”(这是上述默认路由中的默认操作。)

答案 3 :(得分:0)

尝试将routes.LowercaseUrls = true;添加到路由配置中,因为您似乎更喜欢小写版本的路由:

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

            routes.LowercaseUrls = true;

            routes.MapRoute(
                name: "TrailersOverview",
                url: "{TrailersOverview}/{action}/{vendid}",
                defaults: new { controller = "TrailersOverview", action = "Index", vendId = UrlParameter.Optional }
            );

             routes.MapRoute(
                "MyCustomRoute", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "login", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

            routes.MapRoute(
                name: "Default",
                url: "{*}",
                defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

对于默认路由,我想您想提及{*}的网址以匹配其他所有内容?