我如何发送多值来创建操作

时间:2018-11-27 12:29:26

标签: asp.net-mvc model-view-controller entity-framework-6

我有一个医生,我想要从子专业表中添加多对多关系的医生亚专业

我需要从multiselect列表中添加子专业,但是我的控制器仅添加第一个选择,我希望我的create控制器接受所有通过的子专业并创建它

我的模特

public partial class DoctorSubSpecialty
{
    public int Id { get; set; }
    public Nullable<int> DoctorId { get; set; }
    public Nullable<int> SubSpecialtyId { get; set; }

    public virtual DoctorProfile DoctorProfile { get; set; }
    public virtual  SubSpecialty SubSpecialty { get; set; }
}

}

创建动作

public ActionResult Create()
    {
            ViewBag.DoctorId = new SelectList(db.DoctorProfiles, "Id", "FullName");
            ViewBag.SubSpecialtyId = new MultiSelectList(db.SubSpecialties, "id", "Name");
            return View();
        }

创建后期操作

 [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Create([Bind(Include = "Id,DoctorId,SubSpecialtyId")] DoctorSubSpecialty doctorSubSpecialty)
    {

            DoctorSubSpecialty doctorSub = db.DoctorSubSpecialties.Where(d => d.DoctorId == doctorSubSpecialty.DoctorId & d.SubSpecialtyId == doctorSubSpecialty.SubSpecialtyId).FirstOrDefault();
            if (doctorSub == null) { 
            db.DoctorSubSpecialties.Add(doctorSubSpecialty);
            await db.SaveChangesAsync();
            }

我的观点

@using (Html.BeginForm()) 

{     @ Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>DoctorSubSpecialty</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.DoctorId, "DoctorId", htmlAttributes: new { @class = "control-label col-md-2", @id = "DoctorID" })
        <div class="col-md-10">
            @Html.DropDownList("DoctorId", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.DoctorId, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.SubSpecialtyId, "SubSpecialtyId", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("SubSpecialtyId",(MultiSelectList)ViewBag.SubSpecialtyId, htmlAttributes: new { @multiple = "multiple", @class = "form-control" })
            @Html.ValidationMessageFor(model => model.SubSpecialtyId, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>

}

1 个答案:

答案 0 :(得分:1)

针对您的用例创建一个 ViewModel ,它实际上可以传输多个ID。 即您将需要int[]才能将选择绑定到。 ViewModel还可以帮助您摆脱所有这些ViewBag[Bind]的废话。

public class CreateDoctorSubSpecialtyViewModel {

     // These are the selected values to be posted back
     public int DoctorId { get; set; }
     public int[] SubSpecialtyIds { get; set; }

     // These are the possible values for the dropdowns
     public IEnumerable<SelectListItem> DoctorProfiles { get; set; }
     public IEnumerable<SelectListItem> SubSpecialties { get; set; }
}

GET操作-初始化ViewModel并将其传递给View:

[HttpGet]
public ActionResult Create() {

    var doctorProfiles = db.DoctorProfiles.Select(d => 
        new SelectListItem {
            Text = d.FullName,
            Value = d.Id
        }
    ).ToArray();

    var subSpecialties = db.SubSpecialties.Select(s => 
        new SelectListItem {
            Text = s.Name,
            Value = s.id
        }
    ).ToArray();

    var viewModel = new CreateDoctorSubSpecialtyViewModel {
        DoctorProfiles = doctorProfiles,
        SubSpecialties = subSpecialties 
    };

    return View("Create", viewModel);
}

查看“ Create.cshtml”(为清晰起见,删除了样式)-告诉MVC我们要与@model一起使用哪个ViewModel:

@model CreateDoctorSubSpecialtyViewModel
@using (Html.BeginForm("Create", "YourControllerName", FormMethod.Post)) {

    @Html.DropDownListFor(m => m.DoctorId, Model.DoctorProfiles)

    @Html.DropDownListFor(m => m.SubSpecialtyIds, Model.SubSpecialties, new { multiple = "multiple" })

    <input type="submit" />
}

POST操作-使用Linq Contains对多个提交的SubSpecialtyIds进行测试:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(CreateDoctorSubSpecialtyViewModel postData) {

    DoctorSubSpecialty[] allSelectedSubSpecialities = db.DoctorSubSpecialties
        .Where(d => d.DoctorId == postData.DoctorId 
                 && postData.SubSpecialtyIds.Contains(d.SubSpecialtyId)) 
        .ToArray();

    // ...
}

编辑 @Html.DropDownListFor需要使用IEnumerable<SelectListItem>作为第二个参数。