mvc提交后没有ActionResult方法中的数据

时间:2015-12-01 13:45:46

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 model-view-controller

我有一个索引页面,其中有一个部分用于编写项目名称,并从下拉列表中选择项目类型。

下面我有一个提交按钮,它指向项目控制器中的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无效,并且没有用户输入的信息。

我做错了什么?

3 个答案:

答案 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;
}