C# 如何在自定义属性中正确获取数据库值以验证IdentityRole?
我正在开发一个具有多个角色和用户的Web应用程序。我在.NETCore2中使用了个人用户帐户结构和web应用程序选项(不是mvc,所以我将MVVM与Razor页面一起使用) 目前,每当我在数据表/网格视图中为显示的用户点击“编辑”按钮时,它都会在同一视图中的表单中使用旁边表单中的AJAX调用,使用数据库中的所有对应值填充该表单 它还会填充角色的下拉列表,它将是: 填充下拉列表 这解决了我的问题,但是硬编码的,感觉很脏。我想将其与数据库值进行比较。一个自定义属性应该可以完成这个任务,但是其他帖子上给出的所有示例都不能满足我在本例中的需要。它们都显示了MVC模式的示例,但没有显示MVVM模式。我知道这可能是一种代码结构,但我对mvc不太熟悉,因此无法在mvvm上下文中转换这些示例 企图 到目前为止,我所尝试的: 我的视图模型 棋盘格属性 同样,我使用的是MVVM模式,而不是MVC模式 编辑1 编辑2C# 如何在自定义属性中正确获取数据库值以验证IdentityRole?,c#,validation,razor,mvvm,C#,Validation,Razor,Mvvm,我正在开发一个具有多个角色和用户的Web应用程序。我在.NETCore2中使用了个人用户帐户结构和web应用程序选项(不是mvc,所以我将MVVM与Razor页面一起使用) 目前,每当我在数据表/网格视图中为显示的用户点击“编辑”按钮时,它都会在同一视图中的表单中使用旁边表单中的AJAX调用,使用数据库中的所有对应值填充该表单 它还会填充角色的下拉列表,它将是: 填充下拉列表 这解决了我的问题,但是硬编码的,感觉很脏。我想将其与数据库值进行比较。一个自定义属性应该可以完成这个任务,但是其他帖子上
[ValidateAntiForgeryToken]
公共异步任务OnPostEditAsync(用户模型模型,字符串id)
{
var user=await\u userManager.FindByIdAsync(id);
任务角色用户=_userManager.GetRolesAsync(用户);
IdentityRole currentRole=await_roleManager.FindBynameSync(RoleUser.Result.First());
字符串selectedRole=model.RoleId;
if(user==null | |!ModelState.IsValid)
{
返回页();
}
...
if(selectedRole!=currentRole.Name)
{
wait_userManager.RemoveFromRoleAsync(用户,currentRole.Name);
wait_userManager.AddToRoleAsync(用户,selectedRole);
}
wait_userManager.UpdateAsync(用户);
返回到Topage(…);
}
IoC是什么意思?就我对.net core webapplication(mvvm)和razor页面和identitystores的理解而言,我使用的是依赖注入是的!
<label>Role</label>
<select class="form-control" id="roles" name="RoleId" asp-for="Input.RoleId">
<option value="Admin">User</option>
<option value="Manager">Manager</option>
<option value="User">User</option>
</select>
public class UsersModel : PageModel
{
...
private readonly ApplicationDbContext _dbContext;
public List<IdentityRole> Roles { get; set; }
public UsersModel(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<IactionResult> OnGet()
{
Roles = _dbContext.Roles.ToList();
}
public class UserModel
{
...
[Required]
[Display(Name = "Role")]
public string RoleId { get; set; }
...
}
}
[ValidateAntiForgeryToken]
public async Task<IActionResult> OnPostEditAsync(UserModel model, string id)
{
...
var user = await _userManager.FindByIdAsync(id);
Task<IList<string>> rolesUser = _userManager.GetRolesAsync(user);
IdentityRole currentRole = await _roleManager.FindByNameAsync(rolesUser.Result.First());
string selectedRole = model.RoleId;
if (selectedRole != currentRole.Name)
{
await _userManager.RemoveFromRoleAsync(user, currentRole.Name);
await _userManager.AddToRoleAsync(user, selectedRole);
}
await _userManager.UpdateAsync(user);
return RedirectToPage(...);
...
}
<option value="Not existing">Example</option>
[RegularExpresson("^(Admin|Manager|User)*$)]
public class UserModel
{
...
[Required]
[CheckRole(typeof(IdentityRole))]
[Display(Name = "Role")]
public string RoleId { get; set; }
...
}
public class CheckRoleAttribute : ValidationAttribute
{
public Type ObjectType { get; private set; }
public CheckRoleAttribute(Type type)
{
ObjectType = type;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
// I understand passed value is the given option from the option to validate
// I'd like to obtain my available roles here that are available from the database, so I can validate it and return the correct error message.
}
}
// My Attribute
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
var context = (ApplicationDbContext)validationContext.GetService(typeof(ApplicationDbContext));
if (!context.Roles.Any(p => p.Name == value)) // changed 'p => p' to 'p => p.Name'
{
return ValidationResult.Success;
}
return new ValidationResult($"The selected {value} doesn't exist.");
}
//My model
[Required]
[ValidateRole]
[Display(Name = "Role")]
public string RoleId { get; set; }
}
[ValidateAntiForgeryToken]
public async Task<IActionResult> OnPostEditAsync(UserModel model, string id)
{
var user = await _userManager.FindByIdAsync(id);
Task<IList<string>> rolesUser = _userManager.GetRolesAsync(user);
IdentityRole currentRole = await _roleManager.FindByNameAsync(rolesUser.Result.First());
string selectedRole = model.RoleId;
if (user == null || !ModelState.IsValid)
{
return Page();
}
...
if (selectedRole != currentRole.Name)
{
await _userManager.RemoveFromRoleAsync(user, currentRole.Name);
await _userManager.AddToRoleAsync(user, selectedRole);
}
await _userManager.UpdateAsync(user);
return RedirectToPage(...);
}