Search code examples
asp.netasp.net-corerazor-pagesremote-validation

I am having trouble applying Remote Validation to my Razor Page


I have seen 4 or 5 different videos, two pages and 1 SO link talking about Remote Validation in Razor pages, but I am not getting a few things with these examples. For instance, in the examples, I have seen they are using a variation on a duplicate email checker. Its a simple example and I sort of understand what is going on but I have not been able to extrapolate that out into my project

In my site I have an ItemModel that contains a FromProperty, which is a location. I am trying to check what is entered into that box against a known list of locations. I have added this to my page.

public async Task<JsonResult> OnPostCheckLocation(string location)
{
    LocationModel ValidLocation = await LocationModel.CreateAsync(location);
    var check = ValidLocation.Location;
    var valid = !check.Equals("XXX");
    // "X" is just a placeholder for
    // an invalid location
    return new JsonResult(valid);
}

The ValidLocation will return "XXX" if the entered location doesn't match anything from the database. The next thing I need to do is add the Page Remote attribute, but it isn't clear to me where that goes. I have tried adding to the page model above the ItemModel property.

public ItemModel Item { get; set; } = new ItemModel();

I have tried putting above the FromLocation property in the ItemModel Class and neither one ever hit my OnPostCheckLocation method. I have also tried several other things but I was never able to get it working. This is the Remote Page attribute I used

[PageRemote(ErrorMessage = "Invalid Location",
HttpMethod = "post",
PageHandler = "CheckLocation")]

And lastly my _ValidationScriptsPartial.cshtml does have jquery.validate and jquery.validate.unobtrusive included. So, can someone help me understand where the Remote Page attribute should go and let me know if there is something else that I am missing?


Solution

  • neither one ever hit my OnPostCheckLocation method.

    You can use F12 to see if any error messages in the console.You may meet 400 error.Because in your Remote Page attribute you miss AdditionalFields : A comma separated list of additional fields that should be included in the validation request .The AdditionalFields property must include the request verification token because request verification takes place by default in Razor Pages. If this field is not included in a POST request, the request will fail with a 400 Bad Request status code.

    Razor Pages remote validation requires the property to be validated must be a direct descendent of the PageModel class (i.e. not a property of a child property of the PageModel, also referred to as a "nested property")

    Try to apply the PageRemote attribute to the location property in the razor page, and set the page handler method in the current page:

        [PageRemote(
        ErrorMessage = "Invalid Location",
        AdditionalFields = "__RequestVerificationToken",
        HttpMethod = "post",
        PageHandler = "CheckLocation"
        )]
        [BindProperty]
        public string location { get; set; }
    

    Below is a work demo, you can refer to it:

    IndexModel.cshtml.cs

     public class IndexModel : PageModel
        {
      
            [PageRemote(
        ErrorMessage = "Invalid Location",
        AdditionalFields = "__RequestVerificationToken",
        HttpMethod = "post",
        PageHandler = "CheckLocation"
        )]
            [BindProperty]
            public string location { get; set; }
    
            public async Task<JsonResult> OnPostCheckLocation(string location)
            {
               // LocationModel ValidLocation = await LocationModel.CreateAsync(location);
                var check = "XXX"; //do your staff,just for test
                var valid = !check.Equals("XXX");
                // "X" is just a placeholder for
                // an invalid location
                return new JsonResult(valid);
            }
        }
    

    IndexModel.cshtml:

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    
    <form method="post">
        <input asp-for="location" />
        <span asp-validation-for="location"></span><br>
        <input type="submit" />
    </form>
    
    
    
    @section scripts{
        <partial name="_ValidationScriptsPartial" />
       
    }
    

    result:

    enter image description here