简体   繁体   中英

How to implement custom property validation without data annotations and model

I need to build a form dynamically and also include per-property validation. I have a list of:

public class Field
{
    public string Label { get; set; }
    public string Value { get; set; }
}

And the form is:

<EditForm OnValidSubmit="@OnValidSubmit" OnInvalidSubmit="@OnInvalidSubmit" EditContext="@editContext">
    <DataAnnotationsValidator />
    <CustomFieldValidator @ref="validator" />
    <DxFormLayout CaptionPosition="CaptionPosition.Vertical">
        @{
            foreach (var field in fields)
            {
                <DxFormLayoutItem Caption="@field.Label" ColSpanMd="6" BeginRow="true">
                    <Template Context="editContext">
                        <DxTextBox @bind-Text="@field.Value" BindValueMode="BindValueMode.OnInput" />
                        <ValidationMessage For="@(() => field.Value)" />
                    </Template>
                </DxFormLayoutItem>
            }
        }
        <DxFormLayoutItem ColSpanMd="12">
            <Template Context="editContext">
                <DxButton RenderStyle="ButtonRenderStyle.Primary" RenderStyleMode="ButtonRenderStyleMode.Contained" SubmitFormOnClick="true" Text="Send" />
            </Template>
        </DxFormLayoutItem>
    </DxFormLayout>
    <ValidationSummary />
</EditForm>

I have implemented custom validator as per MS Docs and the current solution works as expected with using a validation summary.

However, the <ValidationMessage For... /> does not work at all.

How can I get per-property validation to work?

Note this is not a ANSWER, but there's not enough room in comments to share this.

I can't see all the code, but a little explanation may help you understand your problem. ValidationSummary will grab all the messages from the ValidationMessageStore , so your validator is writing messages. The problem is how you are constructing the FieldIdentifier used by the store to tag messages when you log them to the store and then how ValidationMessage uses FieldIdentifier to pick the right message to display.

Your validator will be doing something like:

var fi = new FieldIdentifier(this.Model, this.FieldName);
this.ValidationMessageStore.Add(fi, this.Messages);

ValidationMessage is doing:

_fieldIdentifier = FieldIdentifier.Create(For);

To build a FieldIdentifier from For and

EditContext.GetValidationMessages(_fieldIdentifier)

to get the messages for _fieldIdentifier .

Your problem is you are using a list of fields and FieldIdentifier doesn't really cater for that.

Maybe you should consider a custom ValidationMessage . Grab the code from the AspNetCore Repo here .

I'm currently working on custom validator and how to resolve this issue, but I'm not there yet with code I could share.

My be you can try like below and get a workaround!

In the View put the following code:

  @Html.ValidationMessageFor(model => model.Label)
  @Html.ValidationMessageFor(model => model.Value)

Then in your controller put the following code:

ModelState.AddModelError("Label", "Error Message for Label Property")
ModelState.AddModelError("Value", "Error Message for Value Property")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM