我正在尝试在MVC 5中创建的用户上保存一个多选列表,但是这些值没有保存。值仅在编辑时保存。由于某种原因,它无法在创建上工作,并且问题似乎与身份用户有关。我在另一个实体的不同控制器中实现了相同的方法,并且效果很好。
我正在尝试通过以下代码向用户分配多位医疗专业人员。我没有收到任何错误或保存中断,只是没有保存值。
任何人都可以看看我的代码,并为我解决这个问题。
以下是与创建用户有关的控制器代码:
public ActionResult Create()
{
PopulateDepartmentsDropDownList();
PopulateSuperiorsDropDownList();
// Show a list of available groups:
ViewBag.GroupsList = new SelectList(this.GroupManager.Groups, "Id", "Name");
var applicationUser = new ApplicationUser();
applicationUser.HealthProfessionals = new List<HealthProfessional>();
PopulateAssignedHealthProfessionals(applicationUser);
return View();
}
[HttpPost]
public async Task<ActionResult> Create([Bind(Exclude = "ProfilePicture")]RegisterViewModel userViewModel, ApplicationUser applicationUser, string[] selectedHealthProfessionals, params string[] selectedGroups)
{
if (selectedHealthProfessionals != null)
{
applicationUser.HealthProfessionals = new List<HealthProfessional>();
foreach (var healthProfessional in selectedHealthProfessionals)
{
var healthProfessionalToAdd = db.HealthProfessionals.Find(int.Parse(healthProfessional));
applicationUser.HealthProfessionals.Add(healthProfessionalToAdd);
}
}
if (ModelState.IsValid)
{
// To convert the user uploaded Photo as Byte Array before save to DB
byte[] imageData = null;
if (Request.Files.Count > 0)
{
HttpPostedFileBase poImgFile = Request.Files["UserPhoto"];
using (var binary = new BinaryReader(poImgFile.InputStream))
{
imageData = binary.ReadBytes(poImgFile.ContentLength);
}
}
var user = new ApplicationUser
{
UserName = userViewModel.Email,
FirstName = userViewModel.FirstName,
LastName = userViewModel.LastName,
Position = userViewModel.Position,
DepartmentID = userViewModel.DepartmentID,
SuperiorID = userViewModel.SuperiorID,
OfficeNumber = userViewModel.OfficeNumber,
CellNumber = userViewModel.CellNumber,
Email = userViewModel.Email
};
//Here we pass the byte array to user context to store in db
user.ProfilePicture = imageData;
var adminresult = await UserManager
.CreateAsync(user, userViewModel.Password);
//Add User to the selected Groups
if (adminresult.Succeeded)
{
if (selectedGroups != null)
{
selectedGroups = selectedGroups ?? new string[] { };
await this.GroupManager
.SetUserGroupsAsync(user.Id, selectedGroups);
}
return RedirectToAction("Users");
}
}
ViewBag.Groups = new SelectList(await RoleManager.Roles.ToListAsync(), "Id", "Name");
PopulateDepartmentsDropDownList(userViewModel.DepartmentID);
PopulateSuperiorsDropDownList(userViewModel.SuperiorID);
PopulateAssignedHealthProfessionals(applicationUser);
return View(applicationUser);
}
private void PopulateAssignedHealthProfessionals(ApplicationUser applicationUser)
{
var allHealthProfessionals = db.HealthProfessionals;
var userHealthProfessionals = new HashSet<int>(applicationUser.HealthProfessionals.Select(i => i.HealthProfessionalID));
var viewModel = new List<AssignedHealthProfessionals>();
foreach (var healthProfessional in allHealthProfessionals)
{
viewModel.Add(new AssignedHealthProfessionals
{
HealthProfessionalID = healthProfessional.HealthProfessionalID,
HealthProfessionalName = healthProfessional.Name,
HealthProfessionalSurname = healthProfessional.Surname,
Assigned = userHealthProfessionals.Contains(healthProfessional.HealthProfessionalID)
});
}
ViewBag.HealthProfessionals = viewModel;
}
这是我的创建视图:
@model MyApp.Models.RegisterViewModel
@{
ViewBag.Title = "Create User";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="@Url.Content("~/Content/CSS/dropify.min.css")" rel="stylesheet" type="text/css" />
<div class="m-grid__item m-grid__item--fluid m-wrapper">
<div class="m-subheader ">
<div class="d-flex align-items-center">
<div class="mr-auto">
<h3 class="m-subheader__title m-subheader__title--separator">
Add User
</h3>
<ul class="m-subheader__breadcrumbs m-nav m-nav--inline">
<li class="m-nav__item m-nav__item--home">
<a href="@Url.Action("Dashboard","Home")" class="m-nav__link m-nav__link--icon">
<i class="m-nav__link-icon la la-home"></i>
</a>
</li>
<li class="m-nav__separator">
-
</li>
<li class="m-nav__item">
<a href="@Url.Action("Users","UserManagement")" class="m-nav__link">
<span class="m-nav__link-text">
Users
</span>
</a>
</li>
</ul>
</div>
<div>
</div>
</div>
</div>
@using (Html.BeginForm("Create", "UserManagement", FormMethod.Post, new { @class = "m-form m-form--fit m-form--label-align-right", role = "form", enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="m-content">
<div class="m-portlet m-portlet--mobile">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
User Details
</h3>
</div>
</div>
</div>
<div class="m-portlet__body">
<div class="m-form__section m-form__section--first">
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label>
Email Address
</label>
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
First Name
</label>
@Html.TextBoxFor(m => m.FirstName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.FirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
Last Name
</label>
@Html.TextBoxFor(m => m.LastName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.LastName, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label>
Position
</label>
@Html.TextBoxFor(m => m.Position, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Position, "", new { @class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
Department
</label>
@Html.DropDownList("DepartmentID", null, "Choose Department", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.DepartmentID, "", new { @class = "text-danger" })
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label>
Superior
</label>
@Html.DropDownList("SuperiorID", null, "Choose Superior", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SuperiorID, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>
Password
</label>
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>
Confirm Password
</label>
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>
Office Number
</label>
@Html.TextBoxFor(m => m.OfficeNumber, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.OfficeNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>
Cell Number
</label>
@Html.TextBoxFor(m => m.CellNumber, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.CellNumber, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label>
User Groups
</label>
<div class="m-checkbox-list">
@foreach (var item in (SelectList)ViewBag.GroupsList)
{
<label class="m-checkbox m-checkbox--success">
<input type="checkbox" name="selectedGroups" value="@item.Value">
@Html.Label(item.Text, new { @class = "control-label" })
<span></span>
</label>
}
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>
Health Professionals
</label>
<div class="m-checkbox-list">
@{
int cnt = 0;
List<MyApp.ViewModels.AssignedHealthProfessionals> healthProfessionals = ViewBag.HealthProfessionals;
foreach (var healthProfessional in healthProfessionals)
{
if (cnt++ % 3 == 0)
{
}
<label class="m-checkbox m-checkbox--success">
<input type="checkbox" name="selectedHealthProfessionals" value="@healthProfessional.HealthProfessionalID" @(Html.Raw(healthProfessional.Assigned ? "checked=\"checked\"" : ""))>
@Html.Label(healthProfessional.HealthProfessionalName, new { @class = "control-label" }) @Html.Label(healthProfessional.HealthProfessionalSurname, new { @class = "control-label" })
<span></span>
</label>
}
}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label>
Profile Picture
</label>
<input type="file" name="UserPhoto" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" class="dropify" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="m-portlet__body">
<!-- Form Actions Start -->
<div class="m-portlet">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
Actions
</h3>
</div>
</div>
</div>
<div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions">
<input type="submit" class="btn btn-accent m-btn m-btn--custom m-btn--icon m-btn--air m-btn--pill" value="Save" />
@Html.ActionLink("Cancel", "Users", null, new { @class = "btn m-btn--pill m-btn--air btn-brand m-btn m-btn--custom" })
</div>
</div>
</div>
<!-- Form Actions End -->
</div>
</div>
}
</div>
<script src="@Url.Content("~/Scripts/jquery.min.js")"></script>
<script src="@Url.Content("~/Scripts/dropify.min.js")"></script>
<script>
$(document).ready(function () {
// Basic
$('.dropify').dropify();
// Translated
$('.dropify-fr').dropify({
messages: {
default: 'Glissez-déposez un fichier ici ou cliquez',
replace: 'Glissez-déposez un fichier ou cliquez pour remplacer',
remove: 'Supprimer',
error: 'Désolé, le fichier trop volumineux'
}
});
// Used events
var drEvent = $('#input-file-events').dropify();
drEvent.on('dropify.beforeClear', function (event, element) {
return confirm("Do you really want to delete \"" + element.file.name + "\" ?");
});
drEvent.on('dropify.afterClear', function (event, element) {
alert('File deleted');
});
drEvent.on('dropify.errors', function (event, element) {
console.log('Has Errors');
});
var drDestroy = $('#input-file-to-destroy').dropify();
drDestroy = drDestroy.data('dropify')
$('#toggleDropify').on('click', function (e) {
e.preventDefault();
if (drDestroy.isDropified()) {
drDestroy.destroy();
} else {
drDestroy.init();
}
})
});
</script>
这是编辑功能起作用的控制器:
public async Task<ActionResult> Edit(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ApplicationUser applicationUser = db.Users.Include(h => h.HealthProfessionals).Where(h => h.Id == id).Single();
PopulateAssignedHealthProfessionals(applicationUser);
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
// Display a list of available Groups:
var allGroups = this.GroupManager.Groups;
var userGroups = await this.GroupManager.GetUserGroupsAsync(id);
var model = new EditUserViewModel()
{
Id = user.Id,
Email = user.Email,
FirstName = user.FirstName,
LastName = user.LastName,
Position = user.Position,
DepartmentID = user.DepartmentID,
SuperiorID = user.SuperiorID,
OfficeNumber = user.OfficeNumber,
CellNumber = user.CellNumber
};
foreach (var group in allGroups)
{
var listItem = new SelectListItem()
{
Text = group.Name,
Value = group.Id,
Selected = userGroups.Any(g => g.Id == group.Id)
};
model.GroupsList.Add(listItem);
}
PopulateDepartmentsDropDownList(user.DepartmentID);
PopulateSuperiorsDropDownList(user.SuperiorID);
return View(model);
}
private void PopulateAssignedHealthProfessionals(ApplicationUser applicationUser)
{
var allHealthProfessionals = db.HealthProfessionals;
var userHealthProfessionals = new HashSet<int>(applicationUser.HealthProfessionals.Select(i => i.HealthProfessionalID));
var viewModel = new List<AssignedHealthProfessionals>();
foreach (var healthProfessional in allHealthProfessionals)
{
viewModel.Add(new AssignedHealthProfessionals
{
HealthProfessionalID = healthProfessional.HealthProfessionalID,
HealthProfessionalName = healthProfessional.Name,
HealthProfessionalSurname = healthProfessional.Surname,
Assigned = userHealthProfessionals.Contains(healthProfessional.HealthProfessionalID)
});
}
ViewBag.HealthProfessionals = viewModel;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Email,Id,FirstName,LastName,Position,DepartmentID,SuperiorID,OfficeNumber,CellNumber", Exclude = "ProfilePicture")] EditUserViewModel editUser, ApplicationUser applicationUser, int? id, string[] selectedHealthProfessionals, params string[] selectedGroups)
{
if (ModelState.IsValid)
{
// To convert the user uploaded Photo as Byte Array before save to DB
byte[] imageData = null;
if (Request.Files.Count > 0)
{
HttpPostedFileBase poImgFile = Request.Files["UserPhoto"];
using (var binary = new BinaryReader(poImgFile.InputStream))
{
imageData = binary.ReadBytes(poImgFile.ContentLength);
}
}
var user = await UserManager.FindByIdAsync(editUser.Id);
if (user == null)
{
return HttpNotFound();
}
var applicationUserToUpdate = db.Users.Include(h => h.HealthProfessionals).Where(h => h.Id == id).Single();
if (TryUpdateModel(applicationUserToUpdate, "",
new string[] { }))
{
try
{
UpdateUserHealthProfessionals(selectedHealthProfessionals, applicationUserToUpdate);
db.SaveChanges();
return RedirectToAction("Users");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
PopulateAssignedHealthProfessionals(applicationUserToUpdate);
// Update the User:
user.UserName = editUser.Email;
user.Email = editUser.Email;
user.FirstName = editUser.FirstName;
user.LastName = editUser.LastName;
user.Position = editUser.Position;
user.DepartmentID = editUser.DepartmentID;
user.SuperiorID = editUser.SuperiorID;
user.OfficeNumber = editUser.OfficeNumber;
user.CellNumber = editUser.CellNumber;
//Here we pass the byte array to user context to store in db
user.ProfilePicture = imageData;
await this.UserManager.UpdateAsync(user);
// Update the Groups:
selectedGroups = selectedGroups ?? new string[] { };
await this.GroupManager.SetUserGroupsAsync(user.Id, selectedGroups);
return RedirectToAction("Users");
}
ModelState.AddModelError("", "Something failed.");
PopulateDepartmentsDropDownList(editUser.DepartmentID);
PopulateSuperiorsDropDownList(editUser.SuperiorID);
return View();
}
答案 0 :(得分:0)
方法中的参数有点奇怪。
最好的方法是将用户对象作为参数传递。 https://stackoverflow.com/a/18005264/2114398
要快速修复,您可以通过从方法中删除selectedHealthProfessionals和selectedGroups参数,然后将它们初始化为局部变量来手动更新多选参数
[HttpPost]
public async Task<ActionResult> Create([Bind(Exclude = "ProfilePicture")]RegisterViewModel userViewModel, ApplicationUser applicationUser)
{
var selectedGroups = (Request.Form["selectedGroups"] ?? "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var selectedHealthProfessionals = (Request.Form["selectedHealthProfessionals"] ?? "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
applicationUser.HealthProfessionals = new List<HealthProfessional>();
foreach (var healthProfessional in selectedHealthProfessionals)
{
var healthProfessionalToAdd = db.HealthProfessionals.Find(int.Parse(healthProfessional));
applicationUser.HealthProfessionals.Add(healthProfessionalToAdd);
}
if (ModelState.IsValid)
{
...