我有一個創建視圖和編輯視圖,幾乎完全相同。它們都包含級聯下拉列表。第二個列表的值是正在創建或編輯的數據的一部分。第一個下拉列表僅僅是第二個列表中值的過濾器。使用相對URL的Ajax Jquery post
這兩個視圖都使用相同的腳本,它爲第一個下拉列表中的更改事件附加一個處理程序。處理程序向控制器中的方法發佈帖子。
當我運行創建視圖並更改第一個下拉列表時,它工作正常。第二個列表已更新。當我在編輯視圖中嘗試時,出現500內部服務器錯誤。
我看過Firebug。我在處理程序中休息了一會兒。它在選擇時會在兩種情況下被調用。發送的數據看起來是相同的($(this).serialize()看起來相同)。
螢火蟲控制檯說: 所需的防僞表格字段" __RequestVerificationToken "不存在。 我沒有看到我需要一個調用此方法,但當然有其他方法(操作)需要一個。
雖然昨天之前我從來沒有用過Firebug,但如果知道如何,可能還有很多可以檢查的東西。 (我對MVC和網絡應用程序一般都是全新的。)
我也在我的控制器方法中有一個突破。它僅在創建視圖中調用時纔會被觸發。
在絕望中,我嘗試將呼叫類型更改爲GET而不是POST。這導致一個名爲叫做不同名稱的控制器方法(HttpGet EDIT),我覺得這至少令人不安。
我覺得我調用的方法沒有找到(在編輯中)。相反,嘗試使用其他方法(我不知道哪一種方法),並且該方法需要防僞標記。
編輯: 的新鮮空氣的夾持,我意識到,我當然知道哪些動作被調用:這是HttpPost編輯操作(這需要一個防僞標記)。這當然是正常的提交行爲。調試器中的快速運行證實了這一點。由於這個原因,這次通話失敗的事實很明顯。但爲什麼這個動作被調用呢?
更新: Firebug控制檯指示正在調用不同的操作。在創建案例中是.../_ an_alphanumeric_literal_/Order/PopulateAvtalDDL,這正是我想要的。在編輯案例中,它是.../_ an_alphanumeric_literal_/Order/編輯/PopulateAvtalDDL。這是一個路由問題嗎?如果是這樣,我仍然不明白。兩個調用是由相同的劇本量身定做的,我只有一個路由設置(基本爲MVC 4的缺省路由):
routes.MapRoute(
name: "Default",
url: "_an_alphanumeric_literal_/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
UPDATE: 我終於找到了一些相關的信息:Relative URLs in AJAX requests。 然後它是一個路由問題。如果我將腳本URL從相對的PopulateAvtalDDL
改爲絕對的/_an_alphanumeric_literal_/Order/PopulateAvtalDDL
,它可以在兩個視圖中使用。引用鏈接中的答案指出,路徑與瀏覽器中的當前URL相關。在我的情況下,是http://localhost:51852/_an_alphanumeric_literal_/Order/Edit/6?markedOrderId=0
和http://localhost:51852/_an_alphanumeric_literal_/Order/Create?markedOrderId=0
。當構建相對URL時,最後一個段被替換。在創建案例創建,但在編輯的情況下它是(編輯的數據的ID)。我明白髮生了什麼事!
我當時的解決辦法:
添加過濾器周圍DDL(在兩個視圖)一個div設置的網址:<div id="kundDDL" data-url="@Url.Action("PopulateAvtalDDL", "Order")">
。然後在腳本中訪問該URL url: $('#kundDDL').data('url')
。
這裏是爲創建視圖的代碼:
@model AssetMgmt.Models.OrderEditVM
@using AssetMgmt.Models;
@{
ViewBag.Title = MsgString.LblCreateNew + " order";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm(null, null, FormMethod.Post))
{
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.MarkedOrderId)
<fieldset>
<legend>Filter</legend>
<div class="editor-label">
@Html.LabelFor(m => m.KundId)
</div>
<div class="dropdownlist">
@Html.DropDownListFor(m => m.KundId, Model.KundDropDown, string.Empty)
</div>
<div class="dropdown-validation-error">
@Html.ValidationMessageFor(model => model.KundId)
</div>
</fieldset>
<fieldset>
<legend>Orderdata</legend>
<div id="avtalDDL">
@Html.Partial("_AvtalDDL")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Ordernummer)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Ordernummer)
@Html.ValidationMessageFor(model => model.Ordernummer)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Beställare)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Beställare)
@Html.ValidationMessageFor(model => model.Beställare)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Orderdatum)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Orderdatum)
@Html.ValidationMessageFor(model => model.Orderdatum)
</div>
<p>
<input type="submit" value="@MsgString.LblSave" />
</p>
</fieldset>
}
<div>
@Html.ActionLink(MsgString.LblBack, "Index", new { markedOrderId = Model.MarkedOrderId })
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="~/Scripts/jquery.maskedinput-1.3.1.min.js"></script>
<script type="text/javascript" src="~/Scripts/assetMgmtMasks.js"></script>
<script src="~/Scripts/assetMgmtOrderPopulateDDL.js" type="text/javascript"></script>
}
下面是編輯觀點:
@model AssetMgmt.Models.OrderEditVM
@using AssetMgmt.Models;
@{
ViewBag.Title = MsgString.LblEdit + " order";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm(null, null, FormMethod.Post))
{
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.OrderId)
@Html.HiddenFor(model => model.Timestamp)
@Html.HiddenFor(model => model.MarkedOrderId)
<fieldset>
<legend>Filter</legend>
<div class="editor-label">
@Html.LabelFor(m => m.KundId)
</div>
<div class="dropdownlist">
@Html.DropDownListFor(m => m.KundId, Model.KundDropDown, string.Empty)
</div>
<div class="dropdown-validation-error">
@Html.ValidationMessageFor(model => model.KundId)
</div>
</fieldset>
<fieldset>
<legend>Orderdata</legend>
<div id="avtalDDL">
@Html.Partial("_AvtalDDL")
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Ordernummer)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Ordernummer)
@Html.ValidationMessageFor(model => model.Ordernummer)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Beställare)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Beställare)
@Html.ValidationMessageFor(model => model.Beställare)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Orderdatum)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Orderdatum)
@Html.ValidationMessageFor(model => model.Orderdatum)
</div>
<p>
<input type="submit" value="@MsgString.LblSave" />
</p>
</fieldset>
}
<div>
@Html.ActionLink(MsgString.LblBack, "Index", new { markedOrderId = Model.MarkedOrderId })
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="~/Scripts/jquery.maskedinput-1.3.1.min.js"></script>
<script type="text/javascript" src="~/Scripts/assetMgmtMasks.js"></script>
<script src="~/Scripts/assetMgmtOrderPopulateDDL.js" type="text/javascript"></script>
}
腳本:
$(document).ready(function() {
//Kund select
$('#KundId').change(function() {
$.ajax({
url: 'PopulateAvtalDDL',
type: 'post',
data: $(this).serialize(),
success: function (result) {
$('#avtalDDL').html(result);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.statusText);
alert(thrownError);
}
});
return false;
});
});
控制方法的簽名:
[HttpPost]
public PartialViewResult PopulateAvtalDDL(int kundId = 0)