Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RazorPages Page Remote not working on model

as per https://www.mikesdotnetting.com/article/343/improved-remote-validation-in-razor-pages I followed the tutorial and implemented the PageRemote. However it does not work if applied to a property of a model and I use the model as property.

public class Draft
{
    public int Id { get; set; }
    [PageRemote(ErrorMessage = "Invalid data", AdditionalFields = "__RequestVerificationToken", HttpMethod = "post", PageHandler = "CheckReference")]
    public string Reference { get; set; }

}

[BindProperty]
public Draft Draft { get; set; }

public JsonResult OnPostCheckReference()
{            
    var valid = !Draft.Reference.Contains("12345");
    return new JsonResult(valid);
}

on my page

<tab>
    <tab-item icon="fas fa-arrow-left" url="@Url.Page("../Index")"></tab-item>
    <tab-item icon="fas fa-list" url="@Url.Page("Index")"></tab-item>
    <tab-item icon="fas fa-plus" is-active="true"></tab-item>
</tab>
<form method="post">
    <card>
        <card-header icon="fas fa-plus" title="Draft"></card-header>
        <card-body>

            <input asp-for="Draft.Reference" />
            <span asp-validation-for="Draft.Reference" class="text-danger"></span>

        </card-body>
        <card-footer>
            <button class="btn btn-success"><i class="fas fa-plus"></i> Adicionar </button>
        </card-footer>
    </card>
</form>
@section Scripts{

    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
    <script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.min.js"></script>

}
like image 518
Jackal Avatar asked Dec 14 '19 13:12

Jackal


People also ask

What is remote validation?

Remote Validation is a technique that uses client side script to validate user input on the server without posting the entire form. It is typically used to compare the user input with a dynamic list of values. One example of its use would be to prevent duplicate user names being submitted.

How do I create a new razor page?

To add a new Razor page, just right-click Pages folder or any folder inside Pages and choose Add > Razor Page to add directly. It will open a new window, from where you can choose your Razor page's actual type.

What can you do with razor pages?

Razor Pages is designed to make common patterns used with web browsers easy to implement when building an app. Model binding, Tag Helpers, and HTML helpers work with the properties defined in a Razor Page class.


Video Answer


2 Answers

Remote validation on nested model properties is not straightforward. The framework prefixes all additional fields with the name of the model, so request verification fails, resulting in a 400 error.

The work around is to separate the field that you want to validate remotely from the sub-model, and make it a first class property of the PageModel instead. Then, if ModelState is valid, assign the value to the nested model.

public class Draft
{
    public int Id { get; set; }

    public string Reference { get; set; }

}

[BindProperty]
public Draft Draft { get; set; }

[BindProperty, PageRemote(ErrorMessage = "Invalid data", AdditionalFields = "__RequestVerificationToken", HttpMethod = "post", PageHandler = "CheckReference")]
public string Reference {get;set;}

public JsonResult OnPostCheckReference()
{            
    var valid = !Reference.Contains("12345");
    return new JsonResult(valid);
}

Then in the form:

<input asp-for="Reference" />
<span asp-validation-for="Reference" class="text-danger"></span>
like image 155
Mike Brind Avatar answered Oct 17 '22 04:10

Mike Brind


Remote validation on nested model properties doesn't allow you to specify additional fields on a parent object. The __RequestVerificationToken is always on the root of the model. The source for jquery.validate.unobtrusive.js is looking for fields prefixed with *. and prefixes the model name to them. The asp-for tag helper is adding *. to the beginning of the fields.

You can circumvent this prefixing of *. by manually specifying the attribute in html and removing AdditionalFields from the attribute.

PageRemoteAttribute:

public class Draft
{
    public int Id { get; set; }
    [PageRemote(ErrorMessage = "Invalid data", HttpMethod = "post", PageHandler = "CheckReference")]
    public string Reference { get; set; }

}

Html:

<input asp-for="Reference" data-val-remote-additionalfields="__RequestVerificationToken" />

like image 4
Daniel Leach Avatar answered Oct 17 '22 02:10

Daniel Leach