同样回答这个问题 Html.BeginForm with html attributes asp.net mvc4
我有一个视图的viewmodel,其中包含用于填充下拉列表和列表的集合。所以我不想回归它们,我只想返回模型对象。实际上,我只想返回该模型中的4个字段 - 但这是下一个问题。 通过做这个appraoch,我已经躲过了,但我没有运气,除非我提交整个viewmodel,在这个表格上是荒谬的,因为95%的信息被丢弃。
无论如何,我遇到的问题是我无法将创建帖子中返回的游戏事件变为null以外的任何事件。 create上的gameEvent参数为NULL。
也有点惊讶我还没有找到关于此的大量信息。
控制器:
public ActionResult Create()
{
...
var createEventViewModel = new CreateEventViewModel()
{
Places = places,
Characters = characters,
Event = new GameEvent()
};
return this.View(createEventViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Name,Description,EventType,Duration")] GameEvent gameEvent)
{
...
}
观点:
@model Sisyphus.Web.Models.CreateEventViewModel
@{
ViewBag.Title = "Create Event";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create Event</h2>
<div class="row">
<div class="col-lg-8">
<section id="createEvent">
@using (Html.BeginForm("Create", "Event",
new
{
GameEvent = Model.Event
}, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Event.Name, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Event.Name, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Event.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Event.Description, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextAreaFor(m => m.Event.Description, 10, 30, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Event.Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Event.Duration, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Event.Duration, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Event.Duration, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Event.EventType, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(m => m.Event.EventType)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create Event" class="btn btn-default" />
</div>
</div>
}
</section>
</div>
</div>
模特:
public class GameEvent
{
public string Name { get; set; }
public string Description { get; set; }
public int Duration { get; set; }
public EventType EventType { get; set; }
}
viewmodel :(已向下编辑删除了无关的成员
public class CreateEventViewModel
{
public GameEvent Event { get; set; }
}
编辑: 好的,我刚试了这个
@using (Html.BeginForm("Create", "Event",
new RouteValueDictionary()
{
{"GameEvent", Model.Event}
}, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
游戏事件现在不为空(其中的所有值都是) - 所以不是更接近
答案 0 :(得分:2)
您的回发输入基于class CreateEventViewModel
,例如
@Html.TextBoxFor(m => m.Event.Name, ...
@Html.TextAreaFor(m => m.Event.Description, ...
将生成以下html
<input id="Event_Name" name="Event.Name" value=....
但是,您的帖子操作方法的参数是GameEvent
的类型,而不是CreateEventViewModel
。如果您检查Response.Form.Keys
,则会看到Event.Name
,Event.Description
等,但class GameEvent
具有属性Name
,Description
等,因此值不能为由ModelBinder
您需要将发布方法更改为
public ActionResult Create(CreateEventViewModel model)
{
GameEvent event = model.GameEvent;
// do whatever with GameEvent
您还应该删除new {GameEvent = Model.Event} from the
Html.BeginForm`方法
注意我排除了BindAttibute,因为在这种情况下我不认为它是必要的 - 你似乎想要GameEvent的所有属性,除非你为Places
和Characters
的属性创建输入,无论如何它们都将为null,并且由于您没有访问其他属性,因此没有质量分配漏洞。
其他替代方法是手动创建输入,以便正确映射属性,直接html
<input name="Name" value=@Model.Event.Name />
<input name="Description" value=@Model.Event.Desciption />
或使用助手
var Description = Model.Event.Description;
@Html.TextBoxFor(m => Description)