表单没有击中控制器

Posted

技术标签:

【中文标题】表单没有击中控制器【英文标题】:Form not hitting the controller 【发布时间】:2019-10-04 11:48:51 【问题描述】:

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

我有一个非常简单的登录表单,但是不知何故,当用户按下登录时,页面进入 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>
                    

在我的登录控制器中,我有一个名为 Verify 的简单 ActionResult,带有 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)
    ...

我到底做错了什么?这不像是火箭科学。

编辑2: 我注意到,每当我将 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 
            );
        
    

当我删除路由并将所有内容恢复为默认值时,控制器确实会受到影响。不幸的是,我真的需要这些路由用于应用程序的其余部分:(

【问题讨论】:

【参考方案1】:

有几件事似乎是错误的:

路由配置中缺少您的控制器。 动作和控制器名称顺序错误。

RouteConfig:

默认路由如下所示:

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">

到:

<form asp-controller="Login" asp-action="Verify" method="post">

看看here。

【讨论】:

嗨,Marc,您的意思是路由配置中缺少控制器是什么意思?提前致谢! 谢谢 Marc,但是如果我不能使用默认的 routeconfig 怎么办?登录后应用程序正在使用 Angular。 你可以有不同的路由,但只有你自己知道需要什么......这个问题不属于asp.net mvc。在这种情况下,您应该使用 angular 搜索路由。 怎么样?我正在尝试在任何角度首先被击中之前进行登录。我想我需要在谷歌上搜索自定义路线,而不是深入研究角度。【参考方案2】:
 @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 yourModelPublic string USERNAMEget;set;

并在您的操作方法中使用您的模型对象来获取数据。

【讨论】:

好的,让我再检查一次@Катерина 请尝试将路由中的 url 更改为 controller/action/id 其中 anything @Катерина 还是什么都没有 :( 这个应用程序一直在使用 Angular。我认为这就是他们将路由更改为任何东西的原因。不过,我按照你的建议更改了它,但没有用。真的不知道这里 删除自定义路由并添加默认路由后,它突然起作用了。如何在不删除自定义路由的情况下解决此问题? url 路径遵循您在 route.config 中定义的路由。所以它会按照你的路线进行。@Катерина【参考方案3】:

您的自定义路线(上面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.

您的默认路由非常重要,应该配置为包罗万象,任何可以简单地映射到控制器/动作组合的请求。我怀疑您遇到问题是因为您的默认路线已更改。

接下来,注释掉登录控制器中的RouteRoutePrefix 属性...如果您正确使用“RegisterRoutes”,则几乎不需要[Route("Verify")] 指令。

// [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' 应该会带您进入登录屏幕,因为默认操作是“索引”(这是上面默认路由中的默认设置。)

【讨论】:

感谢您的回复,但错误仍然存​​在:“/”应用程序中的服务器错误。无法找到该资源。说明:HTTP 404。您要查找的资源(或其依赖项之一)可能已被删除、名称已更改或暂时不可用。请检查以下 URL 并确保其拼写正确。【参考方案4】:

尝试将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 
            );
        
    

对于默认路由,我想你想提及* 以匹配其他所有内容?

【讨论】:

感谢您的回复,但它并没有解决错误。是的,关于 * 问题:) 登录控制器是唯一不起作用的控制器还是TrailersOverview的情况相同? 好的,你提交表单时得到的链接是什么?

以上是关于表单没有击中控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何关闭自己的视图控制器并在按钮点击中呈现另一个视图控制器?

rails :: 如何评估 js 响应

远程验证在 ASP.NET MVC 5 中不起作用

Blazor - 如何使用 ICommand 在按钮单击中执行表单提交

尽管手动测试成功,但通过重力表单从 Google 广告点击中捕获的 UTM 参数仍然无效

数据表 Ajax url 未命中控制器操作