表单将发布在 HTML.BeginForm MVC5 中的任何点击事件上
Posted
技术标签:
【中文标题】表单将发布在 HTML.BeginForm MVC5 中的任何点击事件上【英文标题】:Form is getting posted on any click event within the HTML.BeginForm MVC5 【发布时间】:2020-03-27 01:14:15 【问题描述】:任何点击都会发布表单(使用空白模型值提交) html BeginForm 中的事件。由于哪个页面需要更长的时间 是时候响应其他请求了。我使用的是 MVC5,jQuery-3.4.1。
示例控制器代码:
获取请求:
public ActionResult Index()
// Some Logic to load Initial record for user
发布请求:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(ModalClass obj)
// Logic to load Initial record based on filter on submit click
示例查看代码:
@using (Html.BeginForm("Index", "ControllerName", FormMethod.POST, new @id = "formid" ))
@Html.AntiForgeryToken()
// Form Design Using Razor Syntax
<div class="form-group col-md-6 col-xs-12">
<button type="submit" value="submit" class="btn btn-primary">Submit</button>
</div>
输出图像:
图片1:页面设计(出于安全原因,屏蔽了少数字段):
如果我们点击发布页面的任何位置,则位置标记为黄色 具有空模型值。如果我们点击未包含在 Html.BeginFrom 中的绿色细线下方,则不会调用任何事件。
Image2:来自 Chrome 开发者工具的网络调用:
点击下拉菜单以及在任何外部都调用发布请求 控制点击。附加的屏幕截图适用于本地主机,但我们是 在生产上也面临同样的问题。
请帮助我知道背后的原因,我是 MVC 新手 还建议一些方法来避免这种情况,因为我的页面响应越来越 延迟。提前谢谢你。
渲染页面来源:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<link href="/Content/bootstrap.min.css" rel="stylesheet" />
<link href="/Content/bootstrap-extended.css" rel="stylesheet" />
<link href="/Content/font-awesome.min.css" rel="stylesheet" />
<link href="/Content/nprogress.css" rel="stylesheet" />
<link href="/Content/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<link href="/Content/bootstrap-multiselect.css" rel="stylesheet" />
<link href="/Content/Gridmvc.css" rel="stylesheet" />
<link href="/Content/custom.css" rel="stylesheet" />
<script src="/Scripts/jquery-3.4.1.min.js"></script>
<script src="/Scripts/gridmvc.js"></script>
<script type="text/javascript">
$(document).ready(function ()
$('.grid-table').addClass('table-bordered');
window.history.pushState(null, "", window.location.href);
window.onpopstate = function ()
window.history.pushState(null, "", window.location.href);
;
);
</script>
</head>
<body class="nav-md">
<div class="container body full-height">
<div class="main_container full-height">
<div class="right_col" role="main">
<script src="/Scripts/modernizr-2.6.2.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/bootstrap-multiselect.js"></script>
<script src="/Scripts/bootstrap-session-timeout.js"></script>
<script src="/Scripts/respond.js"></script>
<script src="/Scripts/moment.min.js"></script>
<script src="/Scripts/bootstrap-datetimepicker.min.js"></script>
<script src="/Scripts/customNew.js"></script>
<div class="page-title">
</div>
<div class="clearfix"></div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="panel panel-default">
<div class="panel-heading" style="padding:5px 15px">
<div class="panel-title">
<h5 style="margin:5px 0">Title <a class="collapse-link"><i class="fa fa-chevron-up fa-fw"></i></a></h5>
</div>
</div>
<form action="/ControllerName" id="formid" method="post">
<input name="__RequestVerificationToken" type="hidden" value="Ek-WGhdZJz0xTglW6W6LbrCZn2c5wHqXm3VdIAReP71DvhRi7zhD-t9aMCzabOXs4CU8VjEQ9a0vT4I6GbeEuXI9ZAkoWmkgnxNZthcfPFzrKU4CsI5BeQN" />
<div class="panel-body">
<div class="form-horizontal">
<div class="form-group col-md-6 col-xs-12">
<label class="control-label col-md-4 col-xs-6" for="LocationID" style="text-align:left">Locations</label>
<div class="col-md-8 col-xs-6">
<select class="form-control" data-val="true" data-val-number="The field Locations must be a number." data-val-required="The Locations field is required." id="ddlLocation" name="LocationID">
<option value="0">Value1</option>
<option value="1">Value2</option>
</select>
</div>
</div>
<div class="form-group col-md-6 col-xs-12">
<label class="control-label col-md-4 col-xs-6" for="ClusterName" style="text-align:left">Cluster</label>
<div class="col-md-8 col-xs-6">
<select class="form-control" id="ClusterName" name="ClusterName">
<option value="0">Select</option>
<option value="1">Value1</option>
</select>
</div>
</div>
<div class="form-group col-md-6 col-xs-12">
<label class="control-label col-md-4 col-xs-6" for="CustomerName" style="text-align:left">Customer Name</label>
<div class="col-md-8 col-xs-6">
<select class="form-control" id="CustomerName" name="CustomerName"></select>
</div>
</div>
<div class="form-group col-md-6 col-xs-12">
<label class="control-label col-md-4 col-xs-6" for="ProjectName" style="text-align:left">Project Name</label>
<div class="col-md-8 col-xs-6">
<select class="form-control" id="ProjectName" name="ProjectName"></select>
</div>
</div>
<div class="form-group col-md-6 col-xs-12">
<label class="control-label col-md-4 col-xs-6" for="Date" style="text-align:left">Date</label>
<div class="col-md-8 col-xs-6">
<div class="input-group datefield" style="margin-bottom:0px">
<input class="form-control text-box single-line" data-val="true" data-val-date="The field Date must be a date." data-val-required="Please select date" id="txtDate" name="Date" placeholder="Compliance Date" type="datetime" value="" />
<div class="input-group-addon">
<span class="glyphicon glyphicon-calendar" id="dateSearch" style="cursor:pointer"></span>
</div>
<span class="field-validation-valid" data-valmsg-for="Date" data-valmsg-replace="true"></span>
</div>
</div>
</div>
<div class="form-group col-md-6 col-xs-12">
<label class="control-label col-md-4 col-xs-6" for="ParamID" style="text-align:left"> Parameters</label>
<div class="col-md-8 col-xs-6" style="height:34px !important">
<select class="listbox form-control col-md-12" id="ParamID" multiple="multiple" name="ParamID">
<option value="1">Value1</option>
<option value="2">Value2</option>
</select>
</div>
</div>
<div class="form-group col-md-6 col-xs-12">
<button type="submit" value="submit" class="btn btn-primary">Submit</button>
<a class="btn btn-primary float-right" role="button" href="/Controller/DownloadExcel">Download Excel</a>
</div>
<div class="clearfix"></div>
</div>
<hr />
<div class="form-group col-md-12 col-xs-12">
<div class="col-md-5 col-xs-12 col-md-offset-3">
<div class='progress progress_sm'>
<div class='progress-bar bg-green' role='progressbar' style='width:100%;'>
Value2
</div>
</div>
</div>
</div>
<div class="table-responsive Linked">
<div class="grid-mvc" data-lang="en" data-gridname="" data-selectable="true" data-multiplefilters="false">
<div class="grid-wrap">
<table class="table table-striped grid-table">
<thead>
<tr>
<th class="grid-header" style="width:30px;"><div class="grid-header-title"><span></span></div></th>
<th class="grid-header" style="width:30px;"><div class="grid-header-title"><span> </span></div></th>
<th class="grid-header" style="width:30px;"><div class="grid-header-title"><span>Delete</span></div></th>
<th class="grid-header"><div class="grid-filter" data-filterdata="[]" data-name="Name" data-type="System.String" data-widgetdata="null"><span class="grid-filter-btn" title="Filter this column"></span></div><div class="grid-header-title"><a href="?grid-column=Name&grid-dir=0">Name</a></div></th>
</tr>
</thead>
<tbody>
<tr class="grid-row ">
<td class="grid-cell" data-name=""><a class="btn btn-default btn-round" data-backdrop="static" data-modal="" href="/Controller/Action1?Name=Value" ><span class='glyphicon glyphicon-new-window'></span></a></td>
<td class="grid-cell" data-name=""><span title='Non-Compliance' class='status inactive'> </span></td>
<td class="grid-cell" data-name=""><a class="btn btn-danger btn-round" href="/Controller/Action2/Value" onclick="return confirm('Are you sure want to delete this?);"><span class='glyphicon glyphicon-remove'></span></a></td>
<td class="grid-cell" data-name="Name">ABCDE</td>
</tr>
</tbody>
</table>
<div class="grid-footer">
<div class="grid-pager">
<ul class="pagination">
<li class="active"><span>1</span></li>
<li><a href="?grid-page=2">2</a></li>
<li><a href="?grid-page=3">3</a></li>
<li><a href="?grid-page=4">...</a></li>
<li><a href="?grid-page=66">66</a></li>
<li><a href="?grid-page=2">»</a></li>
</ul>
</div>
</div>
</div>
</div>
<style type="text/css">
.table .table-striped .grid-table .dataTable .no-footer
width: 100% !important;
.progress.progress_sm
/*width: 33% !important;*/
float: left;
z-index: auto !important;
display: block;
margin: 0px !important;
position: relative !important;
/* top: 0; */
/* left: 0; */
/*height: 100%;
width: 100%;*/
background-color: #ededed;
background-image: none;
border-radius: 25px;
.progress-bar span
font-weight: bold;
.gridDangerCell
color: red;
</style>
<!-- modal placeholder-->
<div id='myModal' class='modal fade in' data-keyboard="false" data-backdrop="static">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div id='myModalContent' class="modal-"></div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function ()
$(".Linked .grid-row a").click(function ()
$(this).closest('.table').find(".grid-row.grid-row-selected").removeClass("grid-row-selected");
$(this).closest('.grid-row').addClass("grid-row-selected");
);
);
</script>
</div>
</div>
</form>
</div>
</div>
</div>
<span id="progress" class="progress" style="display: none;">
</span>
<style type="text/css">
.progress
z-index: 9999 !important;
display: block;
margin: 0px !important;
position: absolute;
background: url(images/Preloader_3.gif) center no-repeat #80808036;
top: 0;
left: 0;
bottom: 0;
right: 0;
height: 100%;
width: 100%;
</style>
<script type="text/javascript">
$(document).ready(function ()
var ErrorMessage = '';
if (ErrorMessage != "")
alert(ErrorMessage);
$('.se-pre-con').hide();
$("#formID").submit(function (e)
if ($('#formID').valid())
$('.se-pre-con').show();
else
e.preventDefault();
);
$('.listbox').multiselect(
includeSelectAllOption: true,
);
var IsPost = 'False';
if (IsPost == 'False')
$('.listbox').multiselect('selectAll', false);
$('.listbox').multiselect('updateButtonText');
$('.datefield').datetimepicker(
format: 'YYYY-MM-DD',
ignoreReadonly: true,
allowInputToggle: true
);
function CallAjax(data)
var obj = ;
obj.InputDate = data;
$.ajax(
type: "GET",
contentType: "application/json; charset=utf-8",
url: "Controller/Action",
data: obj,
dataType: "json",
beforeSend: function ()
$(".se-pre-con").fadeIn(1000);
,
complete: function ()
$(".se-pre-con").fadeOut(500);
,
success: function (result)
,
error: function (error)
$(".se-pre-con").fadeOut(500);
alert("Something wrong happend.");
);
$('#ddlLocation').on('change', function ()
CallAjax("ABCE");
);
);
</script>
<style type="text/css">
.d-inline
display: inline !important;
</style>
</div>
<footer>
<div class="pull-right">
</div>
<div class="clearfix"></div>
</footer>
</div>
</div>
<div class="se-pre-con"></div>
<style>
.se-pre-con
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('images/Preloader_3.gif')center no-repeat rgba(0, 0, 0, 0.03);
form.NoStyle:after
content: none !important;
</style>
<script>
$(window).on("load", function ()
$('.userName').each(function ()
var text = $(this).text();
var escapeChar = escapeRegExp(text);
text = escapeChar.replace("UserName\\", "");
$(this).text(text);
)
);
function escapeRegExp(string)
return string.replace(/[.*+?^$()|[\]\\]/g, "\$&");
</script>
<script type="text/javascript">
$.sessionTimeout(
keepAliveUrl: '#',
logoutUrl: "Controller/ActionLogout",
redirUrl: "Account/ActionLogout",
warnAfter: 90,
redirAfter: 120,
countdownMessage: 'Redirecting in timer seconds.'
);
//Auto Hide Notification after 5 Sec.
window.setTimeout(function ()
$(".alert").fadeTo(0, 0).slideUp(1500, function ()
$(this).remove();
);
, 4000);
</script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/jquery.dataTables.min.js"></script>
</body>
</html>
事件的控制台输出绑定到表单:
jQuery._data( $("#formID").get(0), "events" );
submit: Array(2), reset: Array(1), keyup: Array(1), focusout: Array(1), focusin: Array(1), …
click: Array(2)
0:
data: undefined
guid: 56
handler: ƒ delegate( event )
guid: 56
arguments: null
caller: null
length: 1
name: "delegate"
prototype: constructor: ƒ
__proto__: ƒ ()
[[FunctionLocation]]: jquery.validate.js:411
1:
data: undefined
guid: 58
handler: ƒ ( event )
guid: 58
arguments: null
caller: null
length: 1
name: ""
prototype: constructor: ƒ
__proto__: ƒ ()
[[FunctionLocation]]: jquery.validate.js:46
submit: Array(2)
0:
data: null
guid: 27
handler: ƒ (e)
guid: 27
arguments: null
caller: null
length: 1
name: ""
prototype: constructor: ƒ
__proto__: ƒ ()
[[FunctionLocation]]: Report:822
1:
data: undefined
guid: 59
handler: ƒ ( event )
guid: 59
arguments: null
caller: null
length: 1
name: ""
prototype: constructor: ƒ
__proto__: ƒ ()
[[FunctionLocation]]: jquery.validate.js:64
customNew.js 代码
function init_sidebar()
var setContentHeight = function ()
$NAV_MENU = $('.nav_menu');
$FOOTER = $('footer');
$RIGHT_COL.css('min-height', $(window).height());
var bodyHeight = $BODY.outerHeight(),
footerHeight = $BODY.hasClass('footer_fixed') ? -10 : $FOOTER.height(),
leftColHeight = $LEFT_COL.eq(1).height() + $SIDEBAR_FOOTER.height(),
contentHeight = bodyHeight < leftColHeight ? leftColHeight : bodyHeight;
contentHeight -= $NAV_MENU.height() + footerHeight;
$RIGHT_COL.css('min-height', contentHeight);
;
$SIDEBAR_MENU.find('a').on('click', function (ev)
var $li = $(this).parent();
if ($li.is('.active'))
$li.removeClass('active active-sm');
$('ul:first', $li).slideUp(function ()
setContentHeight();
);
else
// prevent closing menu if we are on child menu
if (!$li.parent().is('.child_menu'))
$SIDEBAR_MENU.find('li').removeClass('active active-sm');
$SIDEBAR_MENU.find('li ul').slideUp();
else
if ($BODY.is(".nav-sm"))
$SIDEBAR_MENU.find("li").removeClass("active active-sm");
$SIDEBAR_MENU.find("li ul").slideUp();
$li.addClass('active');
$('ul:first', $li).slideDown(function ()
setContentHeight();
);
);
$MENU_TOGGLE.on('click', function ()
if ($BODY.hasClass('nav-md'))
$SIDEBAR_MENU.find('li.active ul').hide();
$SIDEBAR_MENU.find('li.active').addClass('active-sm').removeClass('active');
else
$SIDEBAR_MENU.find('li.active-sm ul').show();
$SIDEBAR_MENU.find('li.active-sm').addClass('active').removeClass('active-sm');
$BODY.toggleClass('nav-md nav-sm');
setContentHeight();
);
$SIDEBAR_MENU.find('a[href="' + CURRENT_URL + '"]').parent('li').addClass('current-page');
$SIDEBAR_MENU.find('a').filter(function ()
return this.href == CURRENT_URL;
).parent('li').addClass('current-page').parents('ul').slideDown(function ()
setContentHeight();
).parent().addClass('active');
setContentHeight();
// fixed sidebar
if ($.fn.mCustomScrollbar)
$('.menu_fixed').mCustomScrollbar(
autoHideScrollbar: true,
theme: 'minimal',
mouseWheel: preventDefault: true
);
$(document).ready(function ()
init_sidebar();
);
【问题讨论】:
完整的表单域和UI代码会给出一个清晰的思路。 向我们展示渲染后的 HTML 代码。 是否为调用相同 javascript 导致表单提交的单个表单元素定义了 onChange 属性? @Cerlin 我已经用渲染的 HTML 代码更新了这个问题。 @Lavin Sharma 没有为任何 from 元素定义 onChange 属性。 Kindle,参考我更新的渲染 HTML。 【参考方案1】:经过大量调试和代码隔离,我们发现了导致点击表单控件时表单发布的代码块。
下面是导致表单发布到 相同的控制器/动作:
<script type="text/javascript">
$.sessionTimeout(
keepAliveUrl: '#', // This is culprit
logoutUrl: "Controller/ActionLogout",
redirUrl: "Account/ActionLogout",
warnAfter: 90,
redirAfter: 120,
countdownMessage: 'Redirecting in timer seconds.'
);
</script>
我们正在使用它来检查用户会话到期情况,并在用户处于活动状态时延长到期时间。我们已经使用 bootstrap-session-timeout.js 来做到这一点。 在此文件中,每次调用 ajax 发布请求时 keepAliveUrl 以检查活动会话并增加会话超时。 如果我们传递值 # 页面将发布到当前控制器/操作方法。
这个问题有三种可能的解决方案:
1.将 ajaxType: 'POST' 显式更改为 'GET',如下所示:
$.sessionTimeout(
keepAliveUrl: '#',
ajaxType: 'GET', // Soultion
logoutUrl: "Controller/ActionLogout",
redirUrl: "Account/ActionLogout",
warnAfter: 90,
redirAfter: 120,
countdownMessage: 'Redirecting in timer seconds.'
);
2。提供单独的 keepAliveUrl 而不是 '#' 将阻止在同一页面上发布。
$.sessionTimeout(
keepAliveUrl: '/keepAlive', // Soultion
logoutUrl: "Controller/ActionLogout",
redirUrl: "Account/ActionLogout",
warnAfter: 90,
redirAfter: 120,
countdownMessage: 'Redirecting in timer seconds.'
);
3.将 keepalive 标志更改为 false,这将阻止每次点击时的 post 请求。
$.sessionTimeout(
keepAliveUrl: '#',
keepAlive: false, // Solution
logoutUrl: "Controller/ActionLogout",
redirUrl: "Account/ActionLogout",
warnAfter: 90,
redirAfter: 120,
countdownMessage: 'Redirecting in timer seconds.'
【讨论】:
以上是关于表单将发布在 HTML.BeginForm MVC5 中的任何点击事件上的主要内容,如果未能解决你的问题,请参考以下文章
Html.BeginForm (ASP.NET MVC) 的问题
mvc Html.BeginForm和Ajax.BeginFrom表单提交
Asp.net Mvc Ajax.BeginForm提交表单