我有一个索引页面,其中有一个部分用于编写项目名称,并从下拉列表中选择项目类型。
下面我有一个提交按钮,它指向项目控制器中的ActionResult方法Create。
代码: [UPDATE] index.cshtml:
@using reqcoll.ViewModels
@model myViewModel
@{
ViewBag.Title = "ReqColl - project";
}
@* First half *@
@using (Html.BeginForm("CreateProject", "Projects"))
{
@Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
@RenderTopHalf(Model.modelProject)
</div>
}
@* Second half *@
@using (Html.BeginForm("CreateRequirement", "Projects"))
{
@Html.AntiForgeryToken()
<div class="form-group" id="pnSecondHalf">
@* Requirements list *@
<div class=" col-md-6 col-lg-6 col-sm-12">
@RenderBottomLeftHalf(Model.modelRequirement)
</div>
@* New/Edit requirements panel *@
<div class="col-md-6 col-lg-6 col-sm-12">
@RenderBottomRightHalf(Model.modelRequirement)
</div>
</div>
}
@* ================================================================================= ============= *@
@* Helpers *@
@helper RenderTopHalf(reqcoll.Models.Project project)
{
<div class=" well">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="row">
@Html.LabelFor(model => project.projectName, htmlAttributes: new { @class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
@Html.TextBoxFor(model => project.projectName, htmlAttributes: new { @class = "ProjectNameInput" })
@Html.ValidationMessageFor(model => project.projectName)
</div>
</div>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="row row-spacing">
@Html.LabelFor(model => project.projectType, htmlAttributes: new { @class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
@Html.DropDownListFor(model => project.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
project.projectType), htmlAttributes: new { @class = "DropDownList" })
@Html.ValidationMessageFor(model => project.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
}
@helper RenderBottomLeftHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
<table class="table">
<tr>
<th>
@if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
@Html.DisplayNameFor(model => model.modelProject.Requirements[0].shortDesc)
}
}
else
{
<label class="label label-primary col-sm-12 col-md-6 col-lg-6">No requirements available</label>
}
</th>
<th></th>
</tr>
@if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
foreach (var item in Model.modelProject.Requirements)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.shortDesc)
</td>
<td>
@* buttons here*@
@*@Html.ActionLink("E", "Edit", new { id = item.requirementID }) |
@Html.ActionLink("D", "Delete", new { id = item.requirementID })*@
</td>
</tr>
}
}
}
</table>
</div>
}
@helper RenderBottomRightHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
@Html.ValidationSummary(true)
<div class="row">
@Html.LabelFor(model => requirement.shortDesc, htmlAttributes: new { @class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
@Html.TextBoxFor(model => requirement.shortDesc, htmlAttributes: new { @class = "RequirementShortDesc" })
@Html.ValidationMessageFor(model => requirement.shortDesc)
</div>
</div>
@Html.ValidationSummary(true)
<div class="row row-spacing">
@Html.LabelFor(model => requirement.longDesc, htmlAttributes: new { @class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12 RequirementLongDesc">
@Html.EditorFor(model => requirement.longDesc)
@Html.ValidationMessageFor(model => requirement.longDesc)
</div>
</div>
@Html.ValidationSummary(true)
<div class="row row-spacing">
@Html.LabelFor(model => requirement.priorityCode, htmlAttributes: new { @class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
@foreach (var value in Enum.GetValues(requirement.priorityCode.GetType()))
{
<div class="control-label col-sm-5 col-md-5 col-lg-5">
@Html.RadioButtonFor(m => requirement.priorityCode, value)
@Html.Label(value.ToString())
</div>
}
@Html.ValidationMessageFor(model => requirement.priorityCode)
</div>
</div>
<input type="hidden" value="" id="hdRequirementID" />
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnReqCreate" class=" col-sm-12 col-md-6 col-lg-6">
@* submit button here *@
@*@Html.ActionLink("Add", "Add", "Requirement", new { @class = "btn btn-default btnSize" })*@
</div>
<div id="pnReqEdit" class=" col-sm-12 col-md-6 col-lg-6">
@* submit buttons here *@
@*@Html.ActionLink("Edit", "Edit", "Requirement", new { @class = "btn btn-default btnSize" })
@Html.ActionLink("Delete", "Delete", "Requirement", new { @class = "btn btn-default btnSize" })*@
</div>
</div>
</div>
}
@section Scripts {
<script>
$(function () {
var pID = $('#hdProjectID').val();
if (pID != null) {
if (pID.length > 0) {
$('#pnEdit').show();
$('#pnCreate').hide();
$('#pnSecondHalf').show();
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
var rID = $('#hdRequirementID').val();
if (rID != null) {
if (rID.length > 0) {
$('#pnReqEdit').show();
$('#pnReqCreate').hide();
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
});
</script>
@Scripts.Render("~/bundles/jqueryval")
}
视图模型:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project modelProject;
public Requirement modelRequirement;
}
}
控制器:
using System.Web.Mvc;
using reqcoll.Models;
using reqcoll.ViewModels;
namespace reqcoll.Controllers
{
public class ProjectsController : Controller
{
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
var vm = new myViewModel()
{
modelProject = new Project() { projectName = "test", projectType = 1 },
modelRequirement = new Requirement() { requirementID = -1 },
};
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateProject(myViewModel vm)
{
if (vm != null)
{
var ab = Request.Form;
// key 1: __RequestVerificationToken
// key 2: project.projectName
// key 3: project.projectType
if (ModelState.IsValid)
{
Project project = vm.modelProject;
// db.Project.Add(project.Item1);
// db.SaveChanges();
// return RedirectToAction("Index");
}
}
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
[原稿]
@using (Html.BeginForm("Create", "Projects"))
{
@Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
<div class=" well">
@Html.ValidationSummary(true)
<div class="row">
@Html.LabelFor(model => model.Item1.projectName, htmlAttributes: new { @class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
@Html.TextBoxFor(model => model.Item1.projectName, htmlAttributes: new { @class = "ProjectNameInput" })
@Html.ValidationMessageFor(model => model.Item1.projectName)
</div>
</div>
@Html.ValidationSummary(true)
<div class="row row-spacing">
@Html.LabelFor(model => model.Item1.projectType, htmlAttributes: new { @class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
@Html.DropDownListFor(model => model.Item1.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
0), htmlAttributes: new { @class = "DropDownList" })
@Html.ValidationMessageFor(model => model.Item1.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
</div>
}
ProjectsController:
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
return View(new Tuple<Project, Requirement, Priority>(new Project(), new Requirement(), new Priority()));
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "projectName,projectType")] Project project)
{
if (ModelState.IsValid)
{
db.Project.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
因此,当单击提交按钮时,将调用ActionResult Create,但ModelState无效,并且没有用户输入的信息。
我做错了什么?
答案 0 :(得分:1)
当您使用model.Item1.projectName和model.Item1.projectType时,您的模型看起来像复杂对象,但在操作方法中,您试图直接获取值,这是错误的。
答案 1 :(得分:1)
[更新代码]
发布新代码后,对模型进行快速更正将使其能够从您的视图中正确绑定:
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project project;
public Requirement requirement;
}
}
[原文]
尽管使用了元组&lt;&gt;键入而不是定义一个类,该类将封装要传递给视图的数据。您仍然可以通过在视图中创建帮助程序来实现所需目的。
@helper RenderMyProject(Project project) {
...
@Html.TextBoxFor(x=> project.projectType)
...
}
然后,您将调用此帮助程序
@RenderMyProject(model.Item1)
区别是什么?
输入的名称将会改变。而不是将[Item1.projectType]发布到响应对象内部,它将看起来像[project.projectType],它将自动映射到您的项目参数。
答案 2 :(得分:0)
发现问题。
我添加了{get;在myViewModel中设置;}到两个模型然后它工作。
这样:
-(BOOL) shouldAutorotate {
return NO;
}
-(UIInterfaceOrientationMask) supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}