表单将发布在 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&amp;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(&#39;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提交表单

ASP.Net MVC 5 Html.BeginForm onsubmit 和具有所需属性的模型

ASP.NET MVC Html.BeginForm用法1

ASP.Net MVC 4 在表单提交时设置“onsubmit”