0

I have a model which should be validated.

public class VersandModalInput
{
    public Courier Courier { get; set; } = Courier.UPS;
    public List<PaketInput> Pakete { get; set; } = new List<PaketInput>();
    public int AnzahlPakete { get; private set; } = 0;
    public bool MailSenden { get; set; } = true;

    public void AddPaket(decimal gewicht = 0)
    {
        Pakete.Add(new PaketInput { Paketnummer = ++AnzahlPakete, Gewicht = gewicht });
    }

    public void RemovePaket()
    {
        Pakete.RemoveAt(--AnzahlPakete);
    }

    public void RemovePaket()
    {
        Pakete.RemoveAt(--AnzahlPakete);
    }
}

My Model as a List. Here is the class:

public class PaketInput
{
    public int Paketnummer { get; set; }
    [Required]
    [Range(0.1, 31)]
    public decimal Gewicht { get; set; }
    public string Trackingnummer { get; set; } = ""; // This should be required is Courier of VersandModalInput is Manual
    public string MbeTrackingnummer { get; set; } = "";
}

I want to have the VersandModalInput become invalid if the Courier of it is Manual and any of the trackingnumbers of from List pakete is empty. The packages are displayed in the frontend and the error should be visible right under the specific field. This is my UI for pakete:

<table class="table table-responsive-xs">
<thead>
    <tr>
        <th>Paket</th>
        <th>Gewicht (Kg)</th>
        @if (BelegVersandInput.Versandtyp == Versandtyp.Manuell)
        {
            <th>Trackingnummer</th>
        }
    </tr>
</thead>
<tbody>
    @foreach (var paket in BelegVersandInput.Pakete)
    {
        <tr>
            <td>@paket.Paketnummer</td>
            <td>
                <InputNumber @bind-Value="paket.Gewicht" class="form-control" />
                <ValidationMessage For="() => paket.Gewicht" />
            </td>
            @if (BelegVersandInput.Versandtyp == Versandtyp.Manuell)
            {
                <td>
                    <InputText @bind-Value="paket.Trackingnummer" class="form-control" />
                    <ValidationMessage For="() => paket.Trackingnummer" />
                </td>
            }
        </tr>
    }
</tbody>

Is there any way to recrete this kind of validation with the classes specified above?

Marvin Klein
  • 1,436
  • 10
  • 33
  • It seems to be the same issue as https://stackoverflow.com/questions/20642328/how-to-put-conditional-required-attribute-into-class-property-to-work-with-web-a – Ewean Jul 06 '20 at 15:39
  • which property? where is class `Paket` – Falco Alexander Jul 06 '20 at 15:42
  • @Ewean thanks for your reply. I've looked into the question you've posted. Unfortunately it doesn't help me in my case because my Model contains a List of another model. I edited my question to make it more clear. You have any idea? – Marvin Klein Jul 07 '20 at 12:35
  • @FalcoAlexander I edited my question above to make it more clear what I want to achive. – Marvin Klein Jul 07 '20 at 12:35

1 Answers1

0

You can use FluentValidation:

install-package FluentValidation

Then try this:

public sealed class BelegVersandInput : Lagerregal.VersandModalInput
{
    public BelegTyp BelegTyp { get; set; }
    public int Belegnummer { get; set; }
    public Versandtyp Versandtyp { get; set; }

    public void Validate()
    {
            var validationResult = new BelegVersandInputValidator().Validate(this);
            if (!validationResult.IsValid)
                throw new Exception(string.Join(',', validationResult.Errors.Select(e => e.ErrorMessage)));
    }
}

public class BelegVersandInputValidator : AbstractValidator<BelegVersandInput>
{
    public BelegVersandInputValidator()
    {
        RuleFor(p=> p.Pakete).NotEmpty().When(p=> p.Versandtyp == Versandtyp.Manual)
    }
}
  • Thank you for your reply. Is there no way to do it with built in features of ASP.NET Core? How do I display the error messages on the correct spot within an ASP.NET Core Blazor server side app? – Marvin Klein Jul 07 '20 at 12:37
  • you dont need to write: string.Join(',', validationResult.Errors.Select(e => e.ErrorMessage). This can be repladed with: validationResult.ToString(",") :) – MatR Jul 07 '20 at 12:42