我有一个控制器Edit
,它在同一操作中执行插入和更新。在那里我对Active Directory
. 如果由于用户输入的用户名不匹配并再次检查而导致插入失败,则应用程序应显示验证错误Active Directory
。由于操作中发生了多个条目,因此即使后面的用户名有效,也应该为该特定用户停止插入。
问题:我的代码目前确实使用了 ModelState 检查,但它无法将验证消息传递给 VIEW,因为在这种情况下模型实际上并没有改变它的状态。
问题:如何在数据库插入特定模型属性(在这种情况下为用户名)之前完成服务器端检查?
假设:用户名检查方法是否应该返回用户名本身,然后可以将其传递给视图以显示错误消息?
限制:无法Annotation
在模型上使用,IsRequired
因为它不是必填字段。即使用户名文本框为空,用户也应该能够编辑当前用户列表并保存。只有在文本框中输入用户名并插入时才需要验证。无法进行客户端检查,Active Directory
因为它会很重。这不是归档验证,而是检查不良数据是否不会进入数据库。
模型:
public class User
{
[Key]
public string username { get; set; }
[Key]
public string role { get; set; }
}
看法:
@model List<Project.ViewModels.UserViewModel>
@using (@Html.BeginForm())
{
<table class="table">
<tr>
<th>User</th>
@for (int i = 0; i < Model[0].Roles.Count; i++)
{
<th>
@Model[0].Roles[i].RoleName
</th>
}
</tr>
@for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>
@if (Model[i].UserName == null)
{
@Html.EditorFor(m=> m[i].UserName)
@Html.ValidationMessageFor(m=> m[i].UserName)
if (!ViewData.ModelState.IsValid)
{
<span class="field-validation-error">
@ViewData.ModelState["UserName"].Errors[0].ErrorMessage
</span>
}
}
else
{
@Html.HiddenFor(m => m[i].UserName)
@Model[i].UserName
}
</td>
@for (int j = 0; j < Model[i].Roles.Count; j++)
{
<td>
@Html.HiddenFor(m => m[i].Roles[j].RoleName)
@Html.CheckBoxFor(m => m[i].Roles[j].IsSelected)
</td>
}
</tr>
}
</table>
<div class="form-actions">
<button id="SubmitUserRoles" type="submit" class="btn btn-success submit" value="Save">Save</button>
</div>
}
<script>
$("#SubmitUserRoles").click(function () {
$.ajax({
url: '@Url.Action("Edit", "Users")',
type: 'POST',
cache: false,
data: JSON.stringify($('form').serialize()),
success: function (data) {
window.location.href = data
}, error: function (xhr, ajaxOptions, error) {
console.log(xhr.status);
console.log("Error: " + xhr.responseText);
}
});
});
});
控制器:
[HttpPost]
public ActionResult Edit(List<UserViewModel> model)
{
var level = model[0].Level;
var location = model[0].Location;
for (int i = 0; i < model.Count; i++)
{
if (model[i].UserName != null)
{
var uName = model[i].UserName;
for (int j = 0; j < model[i].Roles.Count; j++)
{
var uRole = model[i].Roles[j].RoleName;
var uRoleSelected = model[i].Roles[j].IsSelected;
var userWithSpecificRole = db.Users.FirstOrDefault(m => m.username == uName && m.role == uRole);
if (uRoleSelected && userWithSpecificRole == null)
{
if (DoesUserExist(uName))
{
if (ModelState.IsValid)
{
db.Users.Add(new User
{
username = uName,
role = uRole,
});
db.SaveChanges();
}
}
else
ModelState.AddModelError("UserName", "Username does not exist!");
}
}
}
}
return Json(Url.Action("Index", "Users", new {level,location}));
}
检查用户名的方法Active Directory
如下:
private bool DoesUserExist(string username)
{
PrincipalContext domain = new PrincipalContext(ContextType.Domain, "CompanyDomain", "DC=CompanyDomain,dc=com");
UserPrincipal foundUser = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, username);
return foundUser != null;
}