我有一个简单的应用程序,我松散地基于asp.net上的教程中使用的MVC音乐商店,允许用户输入他们正在观看的电视节目的详细信息,以便他们可以跟踪哪些他们在每个节目中都会参与其中。
我的应用程序中的主要实体是Show:
Public class Show
{
// a few automatic properties
public int id { get; set; }
public Genre Genre { get; set; }
}
和流派类
Public partial class Genre
{
public int GenreId { get; set; }
public string Name { get; set; }
public List<Show> Shows { get; set; }
}
我的控制器中的POST编辑方法是由VS为我生成的:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Show show)
{
if (ModelState.IsValid)
{
db.Entry(show).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(show);
}
当我在调试器中检查db时,我可以看到Show对象(当时很多都在数据库中。我用两个播种它,但通常通过表单添加第三个)都具有类型I&#39 ;已输入但在“编辑”操作返回视图后,类型为空,而所有其他值都已更新。这是为什么?
我想也许类型字段是空的,因为我没有实例化它们但我会在哪里这样做?我不想在每次设置节目类型时创建新类型。我只是希望一个节目有一个类型参考,以便我最终允许用户选择一个类型,并看到他们跟随该类型的所有节目。
编辑:这是我的编辑视图。 “详细信息”视图也非常相似。
@model watchedCatalogue2.Models.Show
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>@Html.DisplayFor(m => m.Name)</legend>
@Html.HiddenFor(m => m.id)
<div class="editor-label">
@Html.LabelFor(m => m.Name)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Genre)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Genre.Name)
@Html.ValidationMessageFor(m => m.Genre.Name)
</div>
<div class="editor-label">
@Html.Label("Number of episodes")
</div>
<div class="editor-field">
@Html.EditorFor(m => m.NoEpisodes)
@Html.ValidationMessageFor(m => m.NoEpisodes)
</div>
<div class="editor-label">
@Html.Label("Number of episodes watched")
</div>
<div class="editor-field">
@Html.EditorFor(m => m.NoEpisodesWatched)
@Html.ValidationMessageFor(m => m.NoEpisodesWatched)
</div>
<div class="editor-label">
@Html.Label("Watching State")
</div>
<div class="editor-field">
@Html.DropDownListFor(m => m.State, watchedCatalogue2.Models.Show.WatchStateItems)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Description)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Description)
@Html.ValidationMessageFor(m => m.Description)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
另外,为了更好的衡量,我的控制器中的db引用了我的CatalogueEntities类:
namespace watchedCatalogue2.Models
{
public class CatalogueEntities : DbContext
{
public DbSet<Genre> Genres { get; set; }
public DbSet<Show> Shows { get; set; }
}
}
答案 0 :(得分:2)
问题可能在MVC中,所有数据都没有保留/发布到POST方法上,而只保留在View上作为可编辑元素呈现并包含在模型中。
最简单的解决方法是将其渲染为隐藏字段,如下所示:
MVC 2.0及更早版本:
<%: Html.HiddenFor(m => m.GenreId) %>
剃刀:
@Html.HiddenFor(m => m.GenreId)
如果你使用AJAX或类似的东西,你也可以发送/传递值作为参数。
另请注意,如果您使用ModelState.IsValid功能,则隐藏字段很可能会呈现为null,并且很可能是一个问题。要删除此内容并不总是建议,只需添加ModelState.Remove("TheKey");
,在您的情况下可能是ModelState.Remove("GenreID");
答案 1 :(得分:1)
如果我正确地解决问题,您需要以某种方式在表单上呈现数据以保持数据,同时记住网络是无状态的,如果值不存在则表单已发布,不会被重新绑定到您的视图模型。
在您的观点中包含以下格式:
@ Html.HiddenFor(model =&gt; model.GenreId)
或者,根据您在Get上的网址,您可以更改POST方法签名以包含ID。
答案 2 :(得分:0)
经过一些研究,我注意到示例中的许多模型类都引用了标记为虚拟的其他模型。我想我没有什么可失去的,所以我修改了我的Show类,所以public Genre Genre { get; set; }
现在读取public virtual Genre Genre { get; set; }
。突然间一切正常。我很感激,如果有人知道它的工作原理可以向我解释,因为我到目前为止看到的所有内容都是对延迟加载的引用,但与我的问题无关。
感谢大家的帮助。