简体   繁体   English

C# MVC 控制器被调用两次

[英]C# MVC controller called twice

I am making a C# Razor MVC web app that is geared for Ipad.我正在制作一个适用于 Ipad 的 C# Razor MVC Web 应用程序。 I am using JQuery mobile and Kendo UI.我正在使用 JQuery Mobile 和 Kendo UI。 I have 2 input forms that use the Kendo grid that sit in a JQuery popup window.我有 2 个输入表单,它们使用位于 JQuery 弹出窗口中的 Kendo 网格。

My problem is that the Waste_Read controller is double firing and makes 2 kendo grids.我的问题是,Waste_Read 控制器是双发的,并制作了 2 个剑道网格。 This is unnoticeable in desktop apps but on the ipad 2 grids are visible.这在桌面应用程序中是不明显的,但在 ipad 2 网格上是可见的。

Below is my _Layout.cshtml and Ham.cshtml (which is my view) code.下面是我的 _Layout.cshtml 和 Ham.cshtml(这是我的观点)代码。

Thanks!谢谢!

_Layout.cshtml _Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
@{

if (Session["currentDate"] == null)
{
HttpContext.Current.Session["currentDate"] = DateTime.Today.ToString("yyyy-MM-dd");
}

if (Session["currentShift"] == null)
{
HttpContext.Current.Session["currentShift"] = 1;
}

if (Session["ReportType"] == null)
{
HttpContext.Current.Session["ReportType"] = "Daily";
}

}

<title>@ViewBag.Title</title>
<meta name="viewport" content="initial-scale = 1.0, maximum-scale = 1.0, user-scalable = no, width=device-width" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<link href="~/Resources/Triangle.ico" rel="shortcut icon" type="image/x-icon" />

@Styles.Render("~/Content/mobileCss", "~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")

<link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.common.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.silver.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.silver.min.css")" rel="stylesheet" type="text/css" />

@*<script src="@Url.Content("~/Scripts/kendo/2013.1.319/jquery.min.js")"></script>*@
<script src="@Url.Content("~/Scripts/kendo/2013.1.319/kendo.all.min.js")"></script>
<script src="@Url.Content("~/Scripts/kendo/2013.1.319/kendo.aspnetmvc.min.js")"></script>
@*<script src="@Url.Content("~/Scripts/kendo.modernizr.custom.js")"></script>*@
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

<script type="text/javascript">


//prevents ipad vertical bounce scrolling
document.ontouchmove = function (event) {
event.preventDefault();
}

function UpdateDate() {
UpdateSessionDate();
UpdateSessionShift();
UpdateSessionReportType();

//$('#datepick').val('AT(Session["currentDate"])');

var DatePageType = '@(ViewBag.DatePageType)';

if (DatePageType == "Reporting") {

UpdateCharts();
}
if (DatePageType == "LiveView") {
UpdateViews($('#hoursaver').val());
UpdateLineViews($('#hoursaver').val());
UpdateOverallInfoBox($('#linesaver').val());
UpdateOverviewOfLabourChart()
}
if (DatePageType == "LabourEntry") {
// UpdateViews($('#hoursaver').val());
refreshLabourEntry();
}

}

function UpdateShift() {
UpdateSessionDate();
UpdateSessionShift();

//$('#datepick').val('AT(Session["currentDate"])');

var DatePageType = '@(ViewBag.DatePageType)';

if (DatePageType == "Reporting") {
UpdateCharts();
}
if (DatePageType == "LiveView") {
UpdateViews($('#hoursaver').val());
UpdateLineViews($('#hoursaver').val());
UpdateOverallInfoBox($('#linesaver').val());
}
if (DatePageType == "LabourEntry") {
refreshLabourEntry();

}
}

function pullfrompeviousLoad(objThis) {
var url = $(objThis).data('url') + '?hour=' + $(objThis).data('hour') + '&Shift=' + $(objThis).data('shift') + '&LineName=' + $(objThis).data('line');
window.location.href = url;
}

function menuLoad(objThis) {
var url = $(objThis).data('url');
window.location.href = url;
}

function buttonLoad(objThis) {
var url = $(objThis).data('url') + '?hour=' + $(objThis).data('time');
window.location.href = url;
}

function saveLoad(objThis) {

$('#labourform').submit();
var url = $(objThis).data('url') + '?hour=' + $(objThis).data('time');
window.location.href = url;
return false;
}

// update date session data
function UpdateSessionDate() {

$.post('/SetSession/SetVariable',
{
key: "currentDate",
value: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd")
});

};

// update shift session data
function UpdateSessionShift() {

$.post('/SetSession/SetVariable',
{
key: "currentShift",
value: $('#shift').val()
});

};


// update report type session data
function UpdateSessionReportType() {

$.post('/SetSession/SetVariable',
{
key: "ReportType",
value: $('#ReportType').val()
});

};

function UpdateButtons(h) {
var arrayToModify = [];
var i = 0, j, k, buttonsToCreate, buttonContainer, newButton;
var buttonsToCreate = [];
var now = parseInt(h);

for (var j = (now - 7) ; j <= (now + 7) ; j++) {

if (j >= 0 && j <= 23) {
buttonsToCreate[i] = j;
i++;
}
}

buttonContainer = document.getElementById('ddShift');

for (k = 0; k < buttonsToCreate.length; k++) {

if (buttonsToCreate[k] == parseInt(h) + 1) {
newButton.style.cssText = 'background-color: red;';
}

newButton = document.createElement('input');
newButton.type = 'button';
newButton.value = buttonsToCreate[k];
newButton.id = buttonsToCreate[k];
newButton.onclick = function () {
arrayToModify[arrayToModify.length] = this.id;
$('#hoursaver').val(this.id);
UpdateViews(this.id);
UpdateLineViews(this.id);
};

buttonContainer.appendChild(newButton);
}
};

kendo.culture("en-US");

</script>

</head>

<body>

<div data-role="page" data-theme="b" id="index">

<div data-role="header" data-position="fixed">
<h1>@ViewBag.Title</h1>
<a href="#nav-panel" data-icon="bars" data-iconpos="notext" class="ui-btn-left">Menu</a>

@if (Request.IsAuthenticated)
{
@Html.ActionLink("My Account", "Index", "Account", routeValues: null, htmlAttributes: new { data_icon = "gear" })
}
else
{
@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { data_icon = "gear" })
}


<div class="datepickerbtn" style="width: 212.5px;">

@(Html.Kendo().DatePicker()
.Name("datepicker")
.Events(e =>
{
e.Change("UpdateDate");
})
.Format("yyyy-MM-dd")
.Value((String)Session["currentDate"])
)
</div>

<div class="shiftpickerbtn" id="btnshift">
<select id="shift" name="shift" onchange="UpdateShift()">
<option value="1">Shift 1</option>
<option value="2">Shift 2</option>
</select>
</div>


</div>
<div data-role="content">

@RenderBody()
</div>
<div data-role="footer" style="text-align: center" data-position="fixed">
@RenderSection("footer", false)
</div>
<div data-role="panel" data-position-fixed="true" data-theme="b" data-content-theme="d" id="nav-panel">
<ul data-role="listview" data-theme="a" class="nav-search">
<li data-icon="delete"><a href="#" data-rel="close">Close menu</a></li>
<li><a data-url="@Url.Action("Index", "Home")" onclick="menuLoad(this)">Home</a></li>
<li><a data-url="@Url.Action("Index", "LabourEntry")" onclick="menuLoad(this)">Labour Entry</a></li>
<li><a data-url="@Url.Action("Index", "LiveView")" onclick="menuLoad(this)">Live View</a></li>
<li><a data-url="@Url.Action("Index", "Report")" onclick="menuLoad(this)">Reporting</a></li>
<li><a data-url="@Url.Action("Loin", "ScheduleBuilder")" onclick="menuLoad(this)">Schedule Builder</a></li>
<li><a data-url="@Url.Action("About", "Home")" onclick="menuLoad(this)">About</a></li>
<li><a data-url="@Url.Action("Contact", "Home")" onclick="menuLoad(this)">Contact</a></li>
</ul>

</div>

</div>

@RenderSection("scripts", required: false)
</body>
</html>

Ham.cshtml火腿.cshtml

@model IEnumerable<OPS.Models.LabourSchedule>

@{
ViewBag.Title = "Ham";
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.DatePageType = "LabourEntry";
}

<script>

$(document).ready(function () {

//set the value of the datepicker and Shift via session variables
$('#datepicker').val('@(Session["currentDate"])');
$('#shift').val('@(Session["currentShift"])');
$('#shift').selectmenu('refresh');

$('#lblWasteFormDate').html('@(Session["currentDate"])');

});

function Update_Data() {
return {
CurDate: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd")
};
}

function Read_Data() {
return {
LineName: "Ham",
CurDate: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd"),
ShiftName: @(Session["currentShift"]) + ""
};
}

function Read_DT_Data() {
return {
LineName: "Ham",
CurDate: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd"),
ShiftName: $("#shift").val() + ""
};
}

</script>


@section footer
{
<div data-inline="true">

<div data-inline="true">
@if (ViewBag.curHour > 0)
{                                    
<a data-role="button" href="#" data-url="@Url.Action("Ham", "LabourEntry")" onclick="buttonLoad(this)"  data-icon="arrow-l" data-iconpos="notext" data-theme="c" data-inline="true" data-time="@ViewBag.prevHour"></a>                  
}
@for (var i = ViewBag.curHour - 7; i <= ViewBag.curHour + 7; i++)
{

if (ViewBag.curHour == i)
{                            
<a data-role="button" href="#" data-theme="b" data-inline="true">@i</a>                                
}
else if (@i >= 0 && @i <= 23)
{                             
<a data-role="button" href="#" data-url="@Url.Action("Ham", "LabourEntry")" onclick="buttonLoad(this)" data-theme="c" data-inline="true" data-time="@i">@i</a>                                          

}

}
@if (ViewBag.curHour < 23)
{                                                          
<a data-role="button" href="#" data-url="@Url.Action("Ham", "LabourEntry")" onclick="buttonLoad(this)"  data-icon="arrow-r" data-iconpos="notext" data-theme="c" data-inline="true" data-time="@ViewBag.nextHour">Arrow right</a>                    
}
<a href="#popupMenu" data-rel="popup" data-role="button" data-inline="true" data-transition="slideup" data-icon="grid" data-iconpos="notext" data-theme="b">Options</a>
</div>

</div>
<div data-role="popup" id="popupDownTime" class="ui-content" data-theme="d" data-overlay-theme="a" data-dismissible="false" style="width: 80%; position: relative; margin: 20px auto;">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>

<div id="update-message"></div>
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "DTForm" }))
{

<input type="hidden" name="LineName" value="Ham" />
<table>
<tr>
<td colspan="3">
<label for="categories">Downtime Reason:</label>
@(Html.Kendo().DropDownList()
.Name("DTCatId")
.OptionLabel("Select downtime...")
.HtmlAttributes(new { style = "width:90%;" })
.DataTextField("Name")
.DataValueField("ID")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDowntimeCategories", "LabourEntry");
});
})
)
</td>
</tr>
<tr>
<td>
<label for="txt_DT_Duration">Duration (minutes):</label>
<input type="number" name="DT_Duration" pattern="[0-9]*" id="txt_DT_Duration" value="" />
</td>
<td>
<label for="txt_DT_People"># of People:</label>
<input type="number" name="DT_People" pattern="[0-9]*" id="txt_DT_People" value="" />
</td>
<td>
<label for="sl_Hrs_Type">Hours Type:</label>
<select name="Hrs_Type" id="sl_Hrs_Type" data-role="slider">
<option value="OT">OT</option>
<option value="REG" selected="selected">Reg</option>
</select>
</td>

</tr>
<tr>
<td colspan="3">
<label for="txt_DT_Desc">Description Detail:</label>
<textarea rows="12" name="DT_Desc" id="txt_DT_Desc"></textarea>
</td>
</tr>
<tr>
<td colspan="3">
<input type="submit" name="submit" value="Add Downtime" />
</td>

</tr>
<tr>
<td colspan="3">
@(Html.Kendo().Grid<OPS.Models.DownTime>()
.Name("DTGrid")
.Columns(columns =>
{
columns.Bound(p => p.ID).Hidden(true);
columns.Bound(p => p.DT_ID).Hidden(true);
columns.Bound(p => p.HR_TYPE).Hidden(true);
columns.Bound(p => p.LINE_ID).Hidden(true);
columns.Bound(p => p.SHIFT).Hidden(true);
columns.Bound(p => p.USER_ID).Hidden(true);
columns.Bound(p => p.DT_REASON).Title("Reason");
columns.Bound(p => p.DT_DETAIL).Title("Details");
columns.Bound(p => p.DURATION).Title("Duration (mins)");
columns.Bound(p => p.NUM_EFFECTED).Title("# of People");
})
.ToolBar(toolbar =>
{
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Sortable()
.Scrollable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.ID);
})
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error"))              
.Read(read => read.Action("DT_Read", "LabourEntry")
.Data("Read_DT_Data"))
.Update(update => update.Action("DT_Update", "LabourEntry"))
)
)
</td>
</tr>
</table>

}
</div>

<div data-role="popup" id="popupWaste" class="ui-content" data-theme="d" data-overlay-theme="a" data-dismissible="false" style="width: 90%; position: relative; margin: 20px auto;">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>

<div style="width: 100%;">

<h3>Date: <label id="lblWasteFormDate"></label>
</h3>


@(Html.Kendo().Grid<OPS.Models.LineProductWasteEntry>()
.Name("WasteGrid")
.Columns(columns =>
{

columns.Bound(p => p.Id).Hidden(true);
columns.Bound(p => p.BucketWeight).Hidden(true);
columns.Bound(p => p.LineCategoryId).Hidden(true);
columns.Bound(p => p.LineCategoryProduct).Hidden(true);
columns.Bound(p => p.LineProductId).Hidden(true);
columns.Bound(p => p.ShiftId).Hidden(true);
columns.Bound(p => p.SourceId).Hidden(true);
columns.Bound(p => p.UserId).Hidden(true);
columns.Bound(p => p.CategoryName);
columns.Bound(p => p.ProductName);
columns.Bound(p => p.Value);
columns.Bound(p => p.SourceName);
columns.Bound(p => p.Source);
columns.Bound(p => p.Weight);
columns.Bound(p => p.Weight2);
columns.Bound(p => p.Weight3);
})
.ToolBar(toolbar =>
{
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Sortable()
.Scrollable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.SourceName).Editable(false);
model.Field(p => p.CategoryName).Editable(false);
model.Field(p => p.ProductName).Editable(false);
model.Field(p => p.Value).Editable(false);
})
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error"))        
.Read(read => read.Action("Waste_Read", "LabourEntry")
.Data("Read_Data"))
.Update(update => update.Action("Waste_Update", "LabourEntry")
.Data("Update_Data"))

)

)

</div>
</div>
<div data-role="popup" id="popupMenu" data-theme="a">
<ul data-role="listview" data-inset="true" style="min-width: 270px;" data-theme="a" class="nav-search">
<li><a href="#popupWaste" data-rel="popup" data-position-to="window" data-transition="pop">Add Waste</a></li>
<li><a href="#popupDownTime" data-rel="popup" data-position-to="window" data-transition="pop">Add Downtime</a></li>

</ul>
</div>

}

Only situation where I can think of a form posting twice is when you have a javascript function binded to the click of your submit button which then calls form.submit()只有当你有一个 javascript 函数绑定到你的提交按钮,然后调用 form.submit()

If that is anything like what you are currently doing then try doing e.preventDefault before calling the form.submit()如果这与您目前正在做的事情类似,请在调用 form.submit() 之前尝试执行 e.preventDefault

$('#mySubmitButton').click(function(e) {

         e.preventDefault(); //This prevent the submit button onclick from submitting by itself
         $('#myForm').submit(); //Manually call the form submit
});

$('#myForm').submit(function(e) {
      e.preventDefault(); //Prevent default here as well - this will allow you to do 
                          //your own posts without the defaults running (good for when you want to use ajax)
     // Simple ajax post using whatever action you put in your form 
     if ($(this).valid()) {
           $.ajax({
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function (result) {
                })
           });
     }
});

This will ensure that your form will execute only once这将确保您的表单只会执行一次

In a much more complex setting I noticed my controller got hit more than once.在一个更复杂的设置中,我注意到我的控制器不止一次被击中。 When I remedied the following two things it no longer got a double hit:当我纠正以下两件事时,它不再受到双重打击:

  • IMG tags with src="#" (placeholders for lazy loading images from带有src="#" IMG 标签(用于延迟加载图像的占位符)
    javascript) remove the hashtag ==> src="" javascript) 删除主题标签 ==> src=""

  • @Url.Content("~/some/static/path/some.css") remove the call to @Url.Content("~/some/static/path/some.css")删除调用
    Url.Content ==> "/some/static/path/some.css" (of course that path Url.Content ==> "/some/static/path/some.css" (当然是那个路径
    needs to exist)需要存在)

It is actually not very clear why @Url.Content() is hitting the controller again but thorough testing proved it.实际上不太清楚为什么@Url.Content()再次击中控制器,但彻底的测试证明了这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM