2

I have an unobtrusive validation defined on a class which validates that the number entered is a valid number in the database. I'd prefer not to use a Remote attribute, as it ties me to a specific controller instead of a service, and the class is actually in a library that is not in the MVC Web application. I'd like to use JavaScript as follows:

$.validator.addMethod("validid", function (value, element) { 

    $.ajax({
      url: 'mypage.html',
      success: function(){
        return true;
      },
      error: function(){
        return false;
      }
    });
}); 

$.validator.unobtrusive.adapters.addBool("validid"); 

I know that I can use an addsingleval and pass in all of the valid IDs in an array, but I would prefer the method to call a service and validate the sing value on the server instead of passing in all possible values in the database. I do recognize the problem of making an asynchronous call and trying to return the value in the function that has already completed, but I'm wondering if there's some other way to make this work.

jbl
  • 15,179
  • 3
  • 34
  • 101
tlbignerd
  • 1,104
  • 9
  • 21

2 Answers2

1

I'd prefer not to use a Remote attribute, as it ties me to a specific controller instead of a service, and the class is actually in a library that is not in the MVC Web application.

If I understand your problem, what prevents you from using the Asp.Net Mvc Remote attribute is that you are only offered routes when you want to specify an arbitrary url.

Maybe you can try with a custom override of the Remote attribute

public class CustomRemote : RemoteAttribute
{
    protected String url { get; set; }

    public CustomRemote(string url)
    {
        this.url = url;
    }

    protected override string GetUrl(ControllerContext controllerContext)
    {
        return url;
    }
}

Then, in your view model :

[CustomRemote("mypage.html")]
public String Id
jbl
  • 15,179
  • 3
  • 34
  • 101
  • Interesting, I hadn't thought of handling it this way. I can give it a try. Does this mean it's not possible to use a custom adapter to get validation rules from the server? – tlbignerd Nov 19 '13 at 11:37
  • @tlbignerd yes, it possible. But most of the complexity lies in the javascript. the jquery.validate remote method is something like 50 lines of js, mostly to handle asynchronous behavior. If the above solution workfs, it might be a good idea. – jbl Nov 19 '13 at 12:21
  • Thanks @jbl. I was looking and I think the solution we'll use is to make the $.ajax call with async: false so that we can keep everyone using a standard validation pattern that doesn't rely on having MVC controllers for the attribute validations. – tlbignerd Nov 19 '13 at 17:41
  • @tlbignerd On second thought, if you want to stay on js-side, you may have just have some javascript set the `data-val-remote-*` html attributes on your element, hence activating clean remote validation with the desired parameters see http://forum.kooboo.com/yaf_postst1171_The-client-side-html-attribute-table-of-Unobtrusive-js-in-ASP-NET-MVC3.aspx for the list of attributes – jbl Nov 20 '13 at 10:06
0

While the answer @jbl provided would work, we are trying to keep the validation logic in a separate class, and would prefer not to include the MVC library. The solution ended up being relatively simple, using an async: false in the method. We ended up with:

$.validator.addMethod("validid", function (value, element) { 

    var isValid = false;

    $.ajax({
      url: 'mypage.html',
      async: false,
      success: function(data){
        isValid = data;
      },
      error: function(){
        isValid = false;
      }
    });

    return isValid;
}); 

$.validator.unobtrusive.adapters.addBool("validid"); 
tlbignerd
  • 1,104
  • 9
  • 21