MVC表单提交为get而不是post

4
客户反馈我的MVC应用程序中的搜索功能第一次尝试返回零结果,但在第二次使用相同搜索字符串进行搜索时会返回结果。
经过一番调查,我发现如果您将页面保持打开状态几分钟(2-5分钟),搜索功能将提交GET请求而不是POST请求,导致搜索字符串的值为NULL。
经过长时间的搜索,我仍然没有找到答案。搜索功能在积极使用应用程序并发布时有效,但是将页面闲置一段时间后,它不再发布,这极大地困扰了我的客户。
以下是表单:
@using (Html.BeginForm("Search", "Student", FormMethod.Post, new { @class = "navbar-form-custom", style = "width:350px;" }))
                        {
                                <input type="text" id="search" name="search" class="form-control" style="height: 43px; width: 300px; border-radius: 5px; padding: 5px; height: 40px; margin-top:5px; border: 2px solid #e6e6e6;" placeholder="Search student" required>
                        }

以及操作:

public ActionResult Search(string search)
    {
        return View(_repo.SearchStudent(search));
    }

我已将 [HttpPost] 添加到该操作中,但仅使 GET 触发时出现 404 错误。
目前我通过将表单切换为 FormMethod.Get 来“解决”这个问题,虽然添加查询字符串并非理想选择。
我仍在寻找适当的解决方案,因为我怀疑应用程序上的其他表单也会显示类似的行为(更改错误地未保存,其他操作抛出 null 异常等)。
我以前制作过类似的项目,并从未遇到过这种行为。这可能是 IIS 问题或相关设置吗?
编辑:找到罪魁祸首了。显然用户的会话超时了,导致重定向到“\Account\Login?ReturnUrl=" Student / Search"”。由于应用程序使用 SSO 会话,用户立即重新登录并且永远不会注意到。然后访问返回 URL 作为 GET 请求,这解释了 POST 突然切换为 GET。将表单切换为 GET 可以解决此问题,因为搜索术语作为查询字符串传递,因此在登录后不会丢失。但是,这确实带来了严重的问题,并解释了很多关于未保存数据的错误报告。
我以前从未遇到过这种问题,但某种方式上这个应用程序的会话长度似乎非常短。一直在寻找设置,但在配置文件中没有找到任何设置(项目的初始阶段是与前同事一起制作的,而且我不管理托管)。
编辑 2:现在我只觉得自己像个白痴。忽略了默认的 Startup.Auth.cs 文件。
app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            },
            ExpireTimeSpan = TimeSpan.FromMinutes(5) //<<DUH OBVIOUSLY
        });            
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

当我注意到问题在一段时间后发生时,本应该是我首先查看的地方。

我的错误。


你的路由是如何定义的? - user47589
表单将通过文本字段上的回车键提交。我知道动作不控制表单,只是为了完整性而添加。 - Doomchild
只需默认路由 “routes.MapRoute( name:“Default”, url:“{controller}/{action}/{id}”, defaults:new { controller =“Home”,action =“Index”,id = UrlParameter.Optional }” - Doomchild
搜索表单是通过提交按钮还是通过 JavaScript 提交的?我不明白为什么让页面空闲一段时间会改变提交方式的原因。 - Martin D.
@MartinD. 表单会在搜索字段中按下回车键时被提交。 - Doomchild
显示剩余2条评论
1个回答

2

只使用默认路由,你的代码将无法工作。如果你在路由配置中不调用MapHttpAttributeRoutes[HttpPost]将不起作用。默认路由配置使用操作名称来确定正在使用的HTTP动词。将你的操作名称更改为PostSearch,它将使用POST。同样,GetSearch将使其响应GET请求。


是的,升级了...这样的东西在我使用 Angular 时真的让我烦透了。他们应该更清楚地说明一下...我也不知道具体指定的地方在哪里。 - Seabizkit
1
这是基于约定的路由的阴暗面。 - user47589

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接