【问题标题】:ASP.Net mvc 5 - Save Parent and child records togetherASP.Net mvc 5 - 一起保存父子记录
【发布时间】:2017-07-25 11:35:30
【问题描述】:

我刚刚开始使用 ASP.net mvc 5,遇到了一个我在下面解释过的问题:

我有UserHistory 模型。并且用户可以拥有多个历史记录。

User模特:

public class User
{
    public int ID { get; set; }
    public string TicketType { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Gender { get; set; }

    public virtual ICollection<History> Histories { get; set; }
}

History模特:

public class History
{
    public int ID { get; set; }
    public int Year { get; set; }
    public int Month { get; set; }
    public int Day { get; set; }

    public virtual User User { get; set; }
}

UserController:

public class UsersController : Controller
{
    private MyDbContext db = new MyDbContext();

    public ActionResult Create()
    {
        var user = new User();
        user.Histories = new List<History>();
        user.Histories.Add(new History { });
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "ID,TicketType,FirstName,LastName")] User user)
    {
        if (ModelState.IsValid)
        {
            db.Users.Add(user);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(user);
    }
}

这是我的表格:

Create.cshtml

@model MyApp.Models.User

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    @Html.Partial("_Form")

    <input type="submit" value="Create" class="btn btn-lg btn-success" />
}

_Form.cshtml:只是为了删除CreateEdit 表单中的重复项

        @model MyApp.Models.User
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.TicketType, htmlAttributes: new { @class = "control-label" })
            @Html.DropDownListFor(model => model.TicketType, new List<SelectListItem>
                    {
                        new SelectListItem() {Text = "OPD", Value="opd"},
                        new SelectListItem() {Text = "Emergency", Value="emergency"},
                    }, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.TicketType, "", new { @class = "text-danger" })
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label" })
            @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
        </div>


        <!-- TODO: fix these form elements which are 
         related to History not User. I am not sure how to do that. 
         Also NOTE that, user fields are saving properly and 
         update is also working. -->


        <div class="form-group">
            <label class="control-label">Year</label>
            <input type="text" value="" class="form-control" />
        </div>

        <div class="form-group">
            <label class="control-label">Month</label>
            <input type="text" value="" class="form-control" />
        </div>

        <div class="form-group">
            <label class="control-label">Day</label>
            <input type="text" value="" class="form-control" />
        </div>

【问题讨论】:

  • 一些选项请参考this answer,使用BeginCollectionItem()的详细示例请参考this one
  • @StephenMuecke:是的,我已经研究过那个解决方案,对我来说,我不会有多个嵌套表单,所以,如果我可以在不使用 BeginCollectionItem 助手的情况下解决它,那会很棒吗?
  • 你是什么意思多个嵌套表单(两个链接都没有 - 特别是因为它不起作用)。不知道为什么您不想在工作中使用正确的工具,但请查看第一个链接中的第二个选项
  • @StephenMuecke:感谢您的帮助,试试BeginCollectionItem() helper。 :) 。阅读第一个链接答案后,您还提供了手动解决方案,也感谢您。
  • @StephenMuecke:我使用BeginCollectionItem() helper 后的最后一个问题是;如何在Create 操作中允许YearMonthDay,即:[Bind(Include = "ID,TicketType,FirstName,LastName")]?请帮忙

标签: c# asp.net asp.net-mvc asp.net-mvc-5 entity-framework-6


【解决方案1】:

您首先创建了 ViewModel。 视图模型结合用户和历史模型 代码下方

Public class userviewmodel
{

     public string TicketType { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set; }
     public string Gender { get; set; }         
     public int Year { get; set; }
     public int Month { get; set; }
     public int Day { get; set; }

 }

第二,你的chtml视图被修改了:

设置模型用户视图模型

 @model MyApp.Models.Userviewmodel

表格设计年月日变更代码

  <Table>
    <thead> 
       <tr>
          <td>Year</td>
          <td>Month</td>
          <td>Day</td>
       </tr>
      </thead>
      <tbody id="tbodyval">
      </tbody>
    </table>


<div class="form-group">
        <label class="control-label">Year</label>
        @Html.EditorFor(model => model.Year, new { htmlAttributes = new { @class = "form-control" } })
 </div>

 <div class="form-group">
    <label class="control-label">Year</label>
    @Html.EditorFor(model => model.month, new { htmlAttributes = new { @class = "form-control" } })
 </div>

 <div class="form-group">
    <label class="control-label">Year</label>
    @Html.EditorFor(model => model.day, new { htmlAttributes = new { @class = "form-control" } })
  </div>
  <input type="button" value="add">

如果添加按钮点击在表体中创建新行 每个内部文本框或 HiddenField Vlaue 辅助当前文本框值

例如 jquery函数

  $("#add").click(function(){
      string row="<tr><td><input type='text' value='$('#year').val(), 
       name='Yearlist'></td>
        <td><input type='text' value='$('#month').val(), name='monthlist'></td>
       <td><input type='text' value='$('#day').val(), name='daylist'></td>
          </tr>"
        $("#tbodyval").append(row);
    });

在控制器中更改您的代码:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create( Userviewmodel usermodel, string[] yearList,string[] monthList,string[] dayList())
{
    if (ModelState.IsValid)
    {

        user model=new user()
        model.TicketType=.usermodel.TicketType;
        model.FirstName=usermodel.FirstName;
        model.LastName=usermodel.LastName;
        model.Gender=usermodel.Gender;

       for(int i=0;i<yearlist.count();i++)
       {
         History child=new History()  

         child.Year=yearlist[i].Year;
         child.month=montList[i].month;
         chile.day=dayList[i].day;            
         model.Histories.add(child);  
       }                      

        db.Users.Add(model);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(user);
}

【讨论】:

  • 您对OP的问题的误解。他们希望能够添加多个 History 对象,而不仅仅是一个(它的集合)
  • @Kari:谢谢,我认为这是一个简单的解决方案,让我试试。在创建动作中我只想保存一个历史记录,即今天的日期,所以我认为不需要添加对象数组。我想,我所缺少的只是对ViewModel 的理解,我最好在继续之前了解它。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 2013-01-28
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多