Remote

The System.Web.Mvc.RemoteAttribute maps to the remote validation method in jQuery Validation.

Here's the model, note that the EmailAddress attribute decorates the sole property on the model:

    using System.Web.Mvc;

    namespace jQuery.Validation.Unobtrusive.Native.Demos.Models
    {
        public class RemoteModel
        {
            [Remote("RemoteSimple", "Demo")]
            public string SimpleErrorMessage { get; set; }

            [Remote("RemoteServerErrorMessage", "Demo")]
            public string ServerErrorMessage { get; set; }
        }
    }
        

Here's the view (which uses the model):

    @model jQuery.Validation.Unobtrusive.Native.Demos.Models.RemoteModel
    @using (Html.BeginForm())
    {
        <div class="row">
            @Html.LabelFor(x => x.SimpleErrorMessage, "Default error message demo.  Only text that begins with the letter \"A\" can be entered:")
            @Html.TextBoxFor(x => x.SimpleErrorMessage, true)
        </div>

        <div class="row">
            @Html.LabelFor(x => x.ServerErrorMessage, "Server error message demo.  Only text that begins with the letter \"B\" can be entered:")
            @Html.TextBoxFor(x => x.ServerErrorMessage, true)
        </div>

        <div class="row">
            <button type="submit" class="btn btn-default">Submit</button>
            <button type="reset" class="btn btn-info">Reset</button>
        </div>
    }
        

Here's the (relevant parts) of the controller. Note the different endpoints for each remote validation:

    using System;
    using System.Web.Mvc;
    using jQuery.Validation.Unobtrusive.Native.Demos.Models;

    namespace jQuery.Validation.Unobtrusive.Native.Demos.Controllers
    {
        public class DemoController : Controller
        {
            // ...

            public JsonResult RemoteSimple(string SimpleErrorMessage)
            {
                return Json(SimpleErrorMessage.StartsWith("a", true, null), JsonRequestBehavior.AllowGet);
            }

            public JsonResult RemoteServerErrorMessage(string ServerErrorMessage)
            {
                return Json((ServerErrorMessage.StartsWith("b", true, null)
                    ? "true"
                    : ServerErrorMessage + " does not begin with \"b\" and this message was sent back from the server as a result..."),
                    JsonRequestBehavior.AllowGet);
            }

            // ...
        }
    }
        

Here's the HTML that the view generates. If you look closely at the data-rule-remote attributes you can see the JSON used to drive the AJAX request. In this example there are 2 properties, url and additionalfields. As you may have guessed url specifies the controller endpoints to hit to perform remote validation. The additionalfields property is a hangover from the default MVC unobtrusive implementation. If we wanted we could strip this out, but since it does no harm it's been left behind for now.

    <form action="/Demo/Remote" method="post">
        <div class="row">
            <label for="SimpleErrorMessage">Default error message demo.  Only text that begins with the letter "A" can be entered:</label>
            <input data-msg-remote="'SimpleErrorMessage' is invalid." 
                data-rule-remote="{&quot;url&quot;:&quot;/Demo/RemoteSimple&quot;,&quot;additionalfields&quot;:&quot;*.SimpleErrorMessage&quot;}"
                id="SimpleErrorMessage" name="SimpleErrorMessage" type="text" value="" />
        </div>
        <div class="row">
            <label for="ServerErrorMessage">Server error message demo.  Only text that begins with the letter "B" can be entered:</label>
            <input data-msg-remote="'ServerErrorMessage' is invalid." 
                data-rule-remote="{&quot;url&quot;:&quot;/Demo/RemoteServerErrorMessage&quot;,&quot;additionalfields&quot;:&quot;*.ServerErrorMessage&quot;}" 
                id="ServerErrorMessage" name="ServerErrorMessage" type="text" value="" />
        </div>
        <div class="row">
            <button type="submit" class="btn btn-default">Submit</button>
            <button type="reset" class="btn btn-info">Reset</button>
        </div>
    </form>
        

Here's the JavaScript that initialises the validation:

  $("form").validate({
      submitHandler: function (form) {
          alert("This is a valid form!");
      }
  });