问题
I am developing an ASP.NET MVC5 project. In my project I am creating remote validation. For that I just created an custom validation attribute to support server-side validation. My remote validator working fine when remote action has to catch only one field. But I am having problems when I try to bind additional field for it. I mean when I validate with extra fields.
Here is my custom remote validation attribute
public class RemoteClientServerAttribute : RemoteAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// Get the controller using reflection
Type controller = Assembly.GetExecutingAssembly().GetTypes()
.FirstOrDefault(type => type.Name.ToLower() == string.Format("{0}Controller",
this.RouteData["controller"].ToString()).ToLower());
if (controller != null)
{
// Get the action method that has validation logic
MethodInfo action = controller.GetMethods()
.FirstOrDefault(method => method.Name.ToLower() ==
this.RouteData["action"].ToString().ToLower());
if (action != null)
{
// Create an instance of the controller class
//object instance = Activator.CreateInstance(controller);
object instance = DependencyResolver.Current.GetService(controller);
// Invoke the action method that has validation logic
var param = new object[] { value };
if(!String.IsNullOrEmpty(this.AdditionalFields))
{
param = new object[] { value , this.AdditionalFields };
}
object response = action.Invoke(instance, param);
if (response is JsonResult)
{
object jsonData = ((JsonResult)response).Data;
if (jsonData is bool)
{
return (bool)jsonData ? ValidationResult.Success :
new ValidationResult(this.ErrorMessage);
}
}
}
}
return ValidationResult.Success;
// If you want the validation to fail, create an instance of ValidationResult
// return new ValidationResult(base.ErrorMessageString);
}
public RemoteClientServerAttribute(string routeName)
: base(routeName)
{
}
public RemoteClientServerAttribute(string action, string controller)
: base(action, controller)
{
}
public RemoteClientServerAttribute(string action, string controller,
string areaName)
: base(action, controller, areaName)
{
}
}
This is my remote validation action with an extra field
public JsonResult IsNameUnique(string Name,int Id)
{
IEnumerable<Category> categories = categoryRepo.Categories.Where(x => x.Name.Trim() == Name);
if (Id > 0)
{
categories = categories.Where(x => x.Id != Id);
}
Category category = categories.FirstOrDefault();
return Json(category==null, JsonRequestBehavior.AllowGet);
}
This is how I am setting annotation in view model
[RemoteClientServer("IsNameUnique","Category","Admin",AdditionalFields="Id",ErrorMessage="Name is already taken")]
public string Name { get; set; }
As you can see I set "Id" for additional field in annotation. But when I submit the form I get the following error in custom validation attribute.
As you can see additional fiels is "Id" as I set in annotation. Not 14 that. 14 is what Id value binded in remote action method.
This is my view
<form method="POST">
@Html.HiddenFor(m=>m.Id)
@Html.TextBoxFor(m => m.Name, new { @class="form-control" })
</form>
How can I catch the value actually binded in remote validation action method in validation attribute? Why is that always "Id". I set "Id" in annotation because I want value of Id binded in action method. How can I solve this problem?
If I convert the type of Id to string in remote action method, its value also become "Id" when I submit the form.
What I think I need to do is I want to retrieve form submitted value using that additional field name. Eg Form["Id"] in validation attribute class. I tried to retrieved property. But it is always zero. How can I retrieve form value using that additional field like this form[AdditionalFields]
.
来源:https://stackoverflow.com/questions/37960095/how-to-create-an-custom-remote-validation-attribute-with-dynamic-additiional-fie