mvc 中的远程验证影响编辑
remote validation in mvc affected edit
我试图通过客户端的远程验证来验证用户名,它在创建模块中添加重复字段时工作正常,但现在它不允许我使用相同的名称编辑记录,它向我显示我为创建定义的相同错误。我尝试了所有可能的方法但没有成功请帮助我。我已经按照这些 link 进行操作,但无论哪种方式都不起作用。
这是我到目前为止尝试过的代码。请专家帮助。
[Required]
[Remote("IsUserAvailable", "User", HttpMethod = "Post", ErrorMessage = "User already exist.", AdditionalFields = "InitialUserName")]
[RegularExpression(@"^(?![\W_]+$)(?!\d+$)[a-zA-Z0-9 ]+$", ErrorMessage = "Invalid UserName ")]
public string UserName { get; set; }
[HttpPost]
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, string initialUserName)
{
var result = uDbContext.Users.FirstOrDefault(a => a.UserName == UserName);
if (result == null)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json(JsonRequestBehavior.AllowGet);
}
@model User.ViewModel.ViewModelUser
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(m => m.User.UserId)
@Html.LabelFor(m.User.UserName)
@Html.TextBoxFor(m => m.User.UserName)
@Html.ValidationMessageFor(m.User.UserName)
@Html.Hidden("initialUserName", Model.User)
</div>
</div>
}
请高手帮忙完成我的作业
您的验证函数不完整。在模型的 UserName
属性 上放置一个 [Required]
属性,然后试试这个:
public JsonResult IsUserAvailable(string userName, string initialUserName)
{
if (userName.Trim().ToLower() != (initialUserName ?? "").Trim().ToLower())
{
var result = YourMethodToCheckTheDatabaseForUsernameIsAvailable(userName);
return Json(result, JsonRequestBehavior.AllowGet);
}
return Json(true, JsonRequestBehavior.AllowGet);
}
User
似乎是一个复杂的对象,所以
@Html.Hidden("initialUserName", Model.User)
可能会生成类似
的内容
<input type="hidden" name="initialUserName" value="YourAssemly.User" ... />
这对验证没有帮助。
您可以通过使用
发回原始名称来忽略验证
@Html.Hidden("InitialUserName", Model.User.UserName)
@Html.Hidden("User.InitialUserName", Model.User.UserName)
然后使用
比较控制器中的值
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, string initialUserName)
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, [Bind(Prefix = "User.InitialUserName")]string initialUserName)
{
if (UserName == initialUserName)
{
// Nothing has changed so signal its valid
return Json(true, JsonRequestBehavior.AllowGet);
}
// Check if the user name already exists
var result = uDbContext.Users.FirstOrDefault(a => a.UserName == UserName);
return Json(result == null, JsonRequestBehavior.AllowGet);
}
旁注:jquery 远程验证是 GET 调用,因此 [HttpPost]
属性不是必需的
编辑
调试 jquery-validate.js
和 jquery-validate-unobtrusive.js
文件后,发现任何 AdditionalFields
的名称属性必须包含与正在验证的 属性 相同的前缀,并且方法中的那些参数也需要 [Bind(Prefix="..")]
属性(请参阅上面的修正)
另一种方法可能是创建一个简单的 class 到 post 返回,例如
public class ValidateUserNameVM
{
public string UserName { get; set; }
public string InitialUserName { get; set; }
}
和
public JsonResult IsUserAvailable([Bind(Prefix = "User")]ValidateUserNameVM model)
{
if (model.UserName == model.InitialUserName)
....
对于 Who Get Null in the second paramter 这个简单的想法可能会有所帮助
public JsonResult IsUserNameAvailable(string Name, string EditNameIssue)
{//it will return true if match found elese it will return false. so i add !
if (Name == EditNameIssue)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
else
{
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
}
转到 Class 并将 string EditNameIssue
添加到 class 以便它可以发送到控制器
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
public string EditNameIssue { get; set; }
}
并编辑 Remote 属性以发送此附加信息 属性
[Remote("IsUserNameAvailable","Employees",ErrorMessage ="User Name Already Taken",AdditionalFields = "EditNameIssue")]
public string Name { get; set; }
如果您添加名称以编辑已被占用的文本框,此逻辑可能会有所帮助
public JsonResult IsUserNameAvailable(string Name, string EditNameIssue)
{//it will return true if match found elese it will return false. so i add !
//Edit Request
if (Name == EditNameIssue)
{
//this mean he didn't change the name
return Json(true, JsonRequestBehavior.AllowGet);
}
else if (Name != EditNameIssue)
{
//if he change the name in the edit go and check if the new name exist
//note if he modify and reenter it origin name it will be also erro he has to reload
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
else if (string.IsNullOrEmpty(EditNameIssue))
{//this mean you came from create request as there is no EditNameIssue in this view
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
else
{//just for the completeness
return Json(false, JsonRequestBehavior.AllowGet);
}
}
我试图通过客户端的远程验证来验证用户名,它在创建模块中添加重复字段时工作正常,但现在它不允许我使用相同的名称编辑记录,它向我显示我为创建定义的相同错误。我尝试了所有可能的方法但没有成功请帮助我。我已经按照这些 link 进行操作,但无论哪种方式都不起作用。
这是我到目前为止尝试过的代码。请专家帮助。
[Required]
[Remote("IsUserAvailable", "User", HttpMethod = "Post", ErrorMessage = "User already exist.", AdditionalFields = "InitialUserName")]
[RegularExpression(@"^(?![\W_]+$)(?!\d+$)[a-zA-Z0-9 ]+$", ErrorMessage = "Invalid UserName ")]
public string UserName { get; set; }
[HttpPost]
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, string initialUserName)
{
var result = uDbContext.Users.FirstOrDefault(a => a.UserName == UserName);
if (result == null)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json(JsonRequestBehavior.AllowGet);
}
@model User.ViewModel.ViewModelUser
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(m => m.User.UserId)
@Html.LabelFor(m.User.UserName)
@Html.TextBoxFor(m => m.User.UserName)
@Html.ValidationMessageFor(m.User.UserName)
@Html.Hidden("initialUserName", Model.User)
</div>
</div>
}
请高手帮忙完成我的作业
您的验证函数不完整。在模型的 UserName
属性 上放置一个 [Required]
属性,然后试试这个:
public JsonResult IsUserAvailable(string userName, string initialUserName)
{
if (userName.Trim().ToLower() != (initialUserName ?? "").Trim().ToLower())
{
var result = YourMethodToCheckTheDatabaseForUsernameIsAvailable(userName);
return Json(result, JsonRequestBehavior.AllowGet);
}
return Json(true, JsonRequestBehavior.AllowGet);
}
User
似乎是一个复杂的对象,所以
@Html.Hidden("initialUserName", Model.User)
可能会生成类似
的内容<input type="hidden" name="initialUserName" value="YourAssemly.User" ... />
这对验证没有帮助。
您可以通过使用
发回原始名称来忽略验证@Html.Hidden("InitialUserName", Model.User.UserName)
@Html.Hidden("User.InitialUserName", Model.User.UserName)
然后使用
比较控制器中的值public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, string initialUserName)
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, [Bind(Prefix = "User.InitialUserName")]string initialUserName)
{
if (UserName == initialUserName)
{
// Nothing has changed so signal its valid
return Json(true, JsonRequestBehavior.AllowGet);
}
// Check if the user name already exists
var result = uDbContext.Users.FirstOrDefault(a => a.UserName == UserName);
return Json(result == null, JsonRequestBehavior.AllowGet);
}
旁注:jquery 远程验证是 GET 调用,因此 [HttpPost]
属性不是必需的
编辑
调试 jquery-validate.js
和 jquery-validate-unobtrusive.js
文件后,发现任何 AdditionalFields
的名称属性必须包含与正在验证的 属性 相同的前缀,并且方法中的那些参数也需要 [Bind(Prefix="..")]
属性(请参阅上面的修正)
另一种方法可能是创建一个简单的 class 到 post 返回,例如
public class ValidateUserNameVM
{
public string UserName { get; set; }
public string InitialUserName { get; set; }
}
和
public JsonResult IsUserAvailable([Bind(Prefix = "User")]ValidateUserNameVM model)
{
if (model.UserName == model.InitialUserName)
....
对于 Who Get Null in the second paramter 这个简单的想法可能会有所帮助
public JsonResult IsUserNameAvailable(string Name, string EditNameIssue)
{//it will return true if match found elese it will return false. so i add !
if (Name == EditNameIssue)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
else
{
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
}
转到 Class 并将 string EditNameIssue
添加到 class 以便它可以发送到控制器
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
public string EditNameIssue { get; set; }
}
并编辑 Remote 属性以发送此附加信息 属性
[Remote("IsUserNameAvailable","Employees",ErrorMessage ="User Name Already Taken",AdditionalFields = "EditNameIssue")]
public string Name { get; set; }
如果您添加名称以编辑已被占用的文本框,此逻辑可能会有所帮助
public JsonResult IsUserNameAvailable(string Name, string EditNameIssue)
{//it will return true if match found elese it will return false. so i add !
//Edit Request
if (Name == EditNameIssue)
{
//this mean he didn't change the name
return Json(true, JsonRequestBehavior.AllowGet);
}
else if (Name != EditNameIssue)
{
//if he change the name in the edit go and check if the new name exist
//note if he modify and reenter it origin name it will be also erro he has to reload
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
else if (string.IsNullOrEmpty(EditNameIssue))
{//this mean you came from create request as there is no EditNameIssue in this view
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
else
{//just for the completeness
return Json(false, JsonRequestBehavior.AllowGet);
}
}