私は作成ビューと編集ビューを持っていますが、ほとんど同じです。どちらにもカスケード ドロップダウン リストが含まれています。2 番目のリストの値は、作成中または編集中のデータの一部です。最初のドロップダウンは、2 番目のリストの値の単なるフィルターです。
両方のビューは、最初のドロップダウン リストの変更イベントのハンドラーをアタッチする同じスクリプトを使用します。ハンドラーは、コントローラー内のメソッドにポストします。
ビューの作成を実行して最初のドロップダウン リストを変更すると、正常に動作します。2 番目のリストが更新されます。編集ビューで試してみると、500 内部サーバー エラーが発生します。
私はFirebugで見てきました。ハンドラーにブレークを入れました。どちらの場合でも、選択時に呼び出されます。送信されるデータは同じように見えます ( $(this).serialize() は同じように見えます)。
Firebug コンソールには次のように表示されます: 必要な偽造防止フォーム フィールド "__RequestVerificationToken" が存在しません。このメソッドを呼び出す必要があるとは思いませんが、もちろん、それを必要とする他のメソッド (アクション) があります。
ただし、昨日まで Firebug を使用したことがないため、方法を知っていれば、さらに多くのことを確認できる可能性があります。(私は MVC と Web アプリケーション全般についてまったくの初心者です。)
また、コントローラー メソッドにも問題があります。作成ビューからのみ呼び出された場合にヒットします。
必死になって、呼び出しタイプを POST ではなく GET に変更してみました。その結果、別の名前のコントローラー メソッド (HttpGet EDIT) が呼び出されました。
呼び出しているメソッドが見つからない気がします (編集中)。代わりに、他の方法 (どの方法かはわかりません) で試行が行われ、その方法には偽造防止トークンが必要です。
編集 : 新鮮な空気を一口飲んで、もちろん、どのアクションが呼び出されるかを知っていることに気付きました。それは HttpPost 編集アクションです (偽造防止トークンが必要です)。もちろん、これは通常のフォーム送信アクションです。デバッガーでクイック実行すると、これが確認されます。この呼び出しが当面の理由で失敗するという事実は明らかです。しかし、なぜこのアクションが呼び出されるのでしょうか。
UPDATE : Firebug コンソールは、さまざまなアクションが呼び出されていることを示します。Create の場合、それは .../_an_alphanumeric_literal_/Order/PopulateAvtalDDL であり、これが私が望むものです。Edit の場合は .../_an_alphanumeric_literal_/Order/ Edit /PopulateAvtalDDL です。これはルーティングの問題ですか?もしそうなら、私はまだそれを理解していません。両方の呼び出しは同じスクリプトから行われ、ルートは 1 つしか設定されていません (基本的には MVC 4 のデフォルト ルート)。
routes.MapRoute(
name: "Default",
url: "_an_alphanumeric_literal_/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
更新:
最終的にいくつかの関連情報を見つけました: 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 が構築されると、最後のセグメントが置き換えられます。Create の場合はCreateですが、Edit の場合は6 (編集済みデータの ID) です。私は何が起こっているのか理解しています!
私の解決策:
両方のビューでフィルター DDL の周りに div を追加して、URL を設定します<div id="kundDDL" data-url="@Url.Action("PopulateAvtalDDL", "Order")">
。次に、スクリプトでその URL にアクセスしますurl: $('#kundDDL').data('url')
。
create ビューのコードは次のとおりです。
@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)