MVC では、1 つの Edit HttpPost は機能しますが、もう 1 つは機能しません。私には何が欠けているのでしょうか?
-
25-09-2019 - |
質問
一般的に、そして SO でグーグル検索してもまだ役に立たないので、次のようにします。
私は最初の MVC アプリケーションをゼロから構築しています。 MVC ミュージック ストアの例 その代わりに、アリーナファイターを作成して互いに戦わせることができる小さなアプリケーションを構築します。(Fighters
そして Fight
EF を介して基になるテーブルにリンクされています)。
両方のコントローラーを持っています Fighters
そしてその Fights
. 。編集 Actionresult
のために Fights
動作していますが、 Fighters
そうではない。変更を保存するボタンを押すと、関連するインデックス ページに戻りますが、変更はコミットされていません。これが私の質問です:なぜこれが失敗するのでしょうか?
から 兵舎コントローラー, 、更新されていない欠陥のある HttpPost Edit (FighterController という名前にする必要がありましたが、気にせず) を使用します。
//
// GET: /Barracks/Edit
public ActionResult Edit(int id)
{
ViewData.Model = _FightDb.Fighters.Single(f => f.Id == id);
return View();
}
//
// POST: /Barracks/Edit
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var fighter = _FightDb.Fighters.Single(f => f.Id == id);
try
{
UpdateModel(fighter, "Fighter");
var x = ViewData.GetModelStateErrors();
_FightDb.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = fighter;
return View(viewModel);
}
}
(ご覧のとおり、含めました このSOの質問からのGetModelStateErrorsトリック, ですが、x の結果は次のようになります。 null
)
これは実際に動作するコントローラー、FightController です。
//
// GET: /Fights/Edit
public ActionResult Edit(int id)
{
var viewModel = new FightDetailsViewModel
{
Fight = _FightDb.Fights.Single(f => f.ID == id),
Fighters = _FightDb.Fighters.ToList()
};
return View(viewModel);
}
//
// POST: /Fights/Edit
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var fight = _FightDb.Fights.Single(f => f.ID == id);
try
{
UpdateModel(fight, "Fight");
_FightDb.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = new FightDetailsViewModel
{
Fight = _FightDb.Fights.Single(f => f.ID == id),
Fighters = _FightDb.Fighters.ToList()
};
return View(viewModel);
}
}
これはファイターズの edit.aspx です。 (コメント後に編集しました)
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc3_EF_BW_Fight.Models.Fighter>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
<h2>Edit</h2>
<%: Html.EditorForModel() %>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
これは、共有で次の Fighter.ascx を使用します。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc3_EF_BW_Fight.Models.Fighter>" %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fighter</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Id) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Id) %>
<%: Html.ValidationMessageFor(model => model.Id) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FighterName) %>
<%: Html.ValidationMessageFor(model => model.FighterName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterStyleDescription) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FighterStyleDescription) %>
<%: Html.ValidationMessageFor(model => model.FighterStyleDescription) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterLongDescription) %>
</div>
<div class="editor-field">
<%: Html.TextAreaFor(model => model.FighterLongDescription) %>
<%: Html.ValidationMessageFor(model => model.FighterLongDescription) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
これは Fights の edit.aspx です
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc3_EF_BW_Fight.ViewModels.FightDetailsViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
<h2>Edit</h2>
<%: Html.EditorFor(model => model.Fight, new { Fighters = Model.Fighters })%>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
これが Fight.ascx です。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc3_EF_BW_Fight.Models.Fight>" %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.ID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ID) %>
<%: Html.ValidationMessageFor(model => model.ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FightName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FightName) %>
<%: Html.ValidationMessageFor(model => model.FightName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter1ID) %><br />
<%: Html.LabelFor(model => model.Fighter1Reference.Value.FighterName)%>
</div>
<div class="editor-field">
<%: Html.DropDownList("Fighter1ID", new SelectList(ViewData["Fighters"] as IEnumerable, "ID", "FighterName", Model.Fighter1ID))%>
<%: Html.ValidationMessageFor(model => model.Fighter1ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter2ID) %>
</div>
<div class="editor-field">
<%: Html.DropDownList("Fighter1ID", new SelectList(ViewData["Fighters"] as IEnumerable, "ID", "FighterName", Model.Fighter1ID))%>
<%: Html.ValidationMessageFor(model => model.Fighter2ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter1Login) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Fighter1Login) %>
<%: Html.ValidationMessageFor(model => model.Fighter1Login) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter2Login) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Fighter2Login) %>
<%: Html.ValidationMessageFor(model => model.Fighter2Login) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FightStatusID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FightStatusID) %>
<%: Html.ValidationMessageFor(model => model.FightStatusID) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
そしてこれが私のFightsのビューモデルです:
public class FightDetailsViewModel
{
public Fight Fight { get; set; }
public List<Fighter> Fighters { get; set; }
}
戦闘機用の ViewModel はありません (とにかく、このシナリオに関係するものはありません)。
あなたが見たいと思うコードを投稿できます。
編集:見てきました MVC 2 での ViewModel パターンの使用 厳密に型指定された HTML ヘルパー そして ASP.NET MVC 2 UpdateModel() がメモリまたはデータベース内の値を更新しない 、しかし、私はまだ解決策を見ていません。
解決
UpdateModel(fighter, "Fighter");
のはちょうどこのUpdateModel(fighter);
ようupdteモデルを呼び出してみてください。違いは、あなたが名前を必要とするので、ファイトの場合、あなたはmodel.Fightためのエディタを呼び出しているときに、名前を必要としないので、戦闘機の場合には、あなたのモデルが直接戦闘機であることを2つの編集の間にあります。同様に、この質問を参照してください:<のhref = "https://stackoverflow.com/questions/3147739/asp-net-mvc2-how-to-get-model-and-model-something-in-the-same-wayを-in-コントローラ/ 3148156#3148156" > asp.net MVC2 - ?コントローラに同じ方法でモデルとmodel.somethingを取得する方法をの