Asp.net 保存多个下拉值后如何填充下拉字段
我有一个个人资料页面,允许用户编辑、选择和保存他们擅长的多种技能。我可以将技能从数据库加载到下拉列表中,但保存后不会填充字段,而是从数据库下拉列表值中删除发布的值,并且在重新加载配置文件页面时,该值/值不会显示在下拉列表中 我还注意到,当我与其他用户登录时,发布的下拉列表值也会从不同用户的下拉列表技能选择中删除 这是Asp.net 保存多个下拉值后如何填充下拉字段,asp.net,asp.net-mvc,asp.net-core,Asp.net,Asp.net Mvc,Asp.net Core,我有一个个人资料页面,允许用户编辑、选择和保存他们擅长的多种技能。我可以将技能从数据库加载到下拉列表中,但保存后不会填充字段,而是从数据库下拉列表值中删除发布的值,并且在重新加载配置文件页面时,该值/值不会显示在下拉列表中 我还注意到,当我与其他用户登录时,发布的下拉列表值也会从不同用户的下拉列表技能选择中删除 这是ApplicationUser类,它扩展了IdentityUser类。技能字段允许用户填写多个技能。这是一节课 public class ApplicationUser : Iden
ApplicationUser
类,它扩展了IdentityUser
类。技能字段允许用户填写多个技能。这是一节课
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Skills = new List<Skill>();
}
public string Name { get; set; }
public ICollection<Skill> Skills { get; set; }
}
这是视图模型
public class ProfileViewModel
{
[Required]
[DataType(DataType.Text)]
public string Name { get; set; }
public List<int> SelectedSkillIds { get; set; }
public MultiSelectList Skills { get; set; }
}
公共类ProfileViewModel
{
[必需]
[数据类型(DataType.Text)]
公共字符串名称{get;set;}
公共列表SelectedSkillIds{get;set;}
公共多选列表技能{get;set;}
}
这是onGet配置文件控制器。我不完全确定我是否知道我在这里做什么
public async Task<IActionResult> Profile()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var profileModel = new ProfileViewModel
{
Name = user.Name,
Skills = new MultiSelectList(_context.Skills.OrderBy(x => x.SkillId), "SkillId", "SkillType", selected),
SelectedSkillIds = user.Skills.Select(x => x.SkillId).ToList()
};
return View(profileModel);
}
公共异步任务配置文件()
{
var user=await\u userManager.GetUserAsync(用户);
if(user==null)
{
返回NotFound($“无法加载ID为“{{u userManager.GetUserId(user)}”的用户”);
}
var profileModel=新ProfileViewModel
{
Name=user.Name,
Skills=新的多重选择列表(_context.Skills.OrderBy(x=>x.SkillId),“SkillId”,“SkillType”,选中),
SelectedSkillIds=user.Skills.Select(x=>x.SkillId.ToList())
};
返回视图(profileModel);
}
这是onPost配置文件控制器
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel profileModel)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (ModelState.IsValid)
{
if (user.Name != profileModel.Name)
{
user.Name = profileModel.Name;
}
foreach (var skillID in profileModel.SelectedSkillIds)
{
user.Skills.Add(new Skill { SkillId = skillID });
}
await _userManager.UpdateAsync(user);
await _signInManager.RefreshSignInAsync(user);
return RedirectToAction("Profile", "Account");
}
}
if (profileModel.SelectedSkillIds != null && profileModel.Skills != user.Skills)
{
List<Skill> userSkills = new List<Skill> { };
foreach (var skillID in profileModel.SelectedSkillIds)
{
userSkills.Add(_context.Skills.FirstOrDefault(x => x.SkillId == skillID));
}
user.Skills = userSkills;
}
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务配置文件(ProfileViewModel profileModel)
{
var user=await\u userManager.GetUserAsync(用户);
if(user==null)
{
返回NotFound($“无法加载ID为“{{u userManager.GetUserId(user)}”的用户”);
}
if(ModelState.IsValid)
{
if(user.Name!=profileModel.Name)
{
user.Name=profileModel.Name;
}
foreach(profileModel.SelectedSkillIds中的var skillID)
{
user.Skills.Add(新技能{SkillId=SkillId});
}
wait_userManager.UpdateAsync(用户);
等待(u signInManager.RefreshSignInAsync)(用户);;
返回重定向到操作(“配置文件”、“帐户”);
}
}
这就是观点
<select data-placeholder="Select your skils" multiple class="chosen-select" asp-for="SelectedSkillIds" asp-items="Model.Skills"></select>
我认为问题与上述代码有关。通过使用它,它将创建一些只包含SkillId值的新技能(不设置SkillType。新运算符用于在数据库中创建新项,但如果我们想从数据库中查找现有项,则无法使用它)。因此,在重新渲染时,dropdownlist不包含这些值
要解决此问题,在更新ApplicationUser时,可以查询技能表以查找相关技能,然后将其分配给ApplicationUser。代码如下:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel profileModel)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (ModelState.IsValid)
{
if (user.Name != profileModel.Name)
{
user.Name = profileModel.Name;
}
//query the database to find the related skills
var selectedSkills = _context.Skills.Where(c => profileModel.SelectedSkillIds.Contains(c.SkillId)).ToList();
//assign the value to the user
user.Skills = selectedSkills;
await _userManager.UpdateAsync(user);
await _signInManager.RefreshSignInAsync(user);
return RedirectToAction("Profile", "Account");
}
}
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务配置文件(ProfileViewModel profileModel)
{
var user=await\u userManager.GetUserAsync(用户);
if(user==null)
{
返回NotFound($“无法加载ID为“{{u userManager.GetUserId(user)}”的用户”);
}
if(ModelState.IsValid)
{
if(user.Name!=profileModel.Name)
{
user.Name=profileModel.Name;
}
//查询数据库以查找相关技能
var selectedSkills=_context.Skills.Where(c=>profileModel.SelectedSkillIds.Contains(c.SkillId)).ToList();
//将值分配给用户
user.Skills=selectedSkills;
wait_userManager.UpdateAsync(用户);
等待(u signInManager.RefreshSignInAsync)(用户);;
返回重定向到操作(“配置文件”、“帐户”);
}
}
重定向到配置文件后,您可以添加调试器以检查数据是否正确,然后再返回视图。实现Zhi的答案成功地为用户保存了技能。或者,我也可以在onPost控制器中发布与此相关的技能
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel profileModel)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (ModelState.IsValid)
{
if (user.Name != profileModel.Name)
{
user.Name = profileModel.Name;
}
foreach (var skillID in profileModel.SelectedSkillIds)
{
user.Skills.Add(new Skill { SkillId = skillID });
}
await _userManager.UpdateAsync(user);
await _signInManager.RefreshSignInAsync(user);
return RedirectToAction("Profile", "Account");
}
}
<select data-placeholder="Select your skils" multiple class="chosen-select" asp-for="SelectedSkillIds" asp-items="Model.Skills"></select>
if (profileModel.SelectedSkillIds != null && profileModel.Skills != user.Skills)
{
List<Skill> userSkills = new List<Skill> { };
foreach (var skillID in profileModel.SelectedSkillIds)
{
userSkills.Add(_context.Skills.FirstOrDefault(x => x.SkillId == skillID));
}
user.Skills = userSkills;
}
if(profileModel.SelectedSkillIds!=null&&profileModel.Skills!=user.Skills)
{
List userSkills=新列表{};
foreach(profileModel.SelectedSkillIds中的var skillID)
{
Add(_context.Skills.FirstOrDefault(x=>x.SkillId==SkillId));
}
user.Skills=userSkills;
}
然而,当页面返回时,我意识到新添加的技能被添加到已删除的技能中。为了解决这个问题,我只需删除所有未在选项中选择但以前为用户保存在数据库中的技能
if (profileModel.SelectedSkillIds != null && profileModel.Skills != user.Skills)
{
List<Skill> tempSkills = new List<Skill> { };
foreach (var skillID in profileModel.SelectedSkillIds)
{
var skill = _context.Skills.Find(skillID);
if (skill != null)
{
try
{
user.Skills.Add(skill);
tempSkills.Add(skill);
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.Message);
return View();
}
}
}
var allSkills = _context.Skills.ToList();
var skills2remove = allSkills.Except(tempSkills);
foreach (var sk in skills2remove)
{
try
{
user.Skills.Remove(sk);
}
catch(Exception ex)
{
ModelState.AddModelError("", ex.Message);
return View();
}
}
}
if(profileModel.SelectedSkillIds!=null&&profileModel.Skills!=user.Skills)
{
List tempSkills=新列表{};
foreach(profileModel.SelectedSkillIds中的var skillID)
{
var skill=_context.Skills.Find(skillID);
如果(技能!=null)
{
尝试
{
user.Skills.Add(skill);
添加(技能);
}
捕获(例外情况除外)
{
ModelState.addmodeleror(“,例如Message”);
返回视图();
}
}
}
var allSkills=_context.Skills.ToList();
var skills2remove=allSkills.Except(临时技能);
foreach(技能中的var sk 2移除)
{
尝试
{
用户.技能.删除(sk);
}
捕获(例外情况除外)
{
ModelState.addmodeleror(“,例如Message”);
返回视图();
}
}
}
这很有用,可以帮助任何人解决类似问题。重新加载页面时,我仍然无法获取保存的值来填充下拉字段。我决定确认
是否选择了skil