0

I have the following EditorTemplate

@model ESG.Web.Models.FileInfo // <-- Changed to BaseFileInfo
@{
    ViewBag.Title = "FileInfoEditorTemplate";
}
<fieldset>
    <table class="fileInfoEdit">
        <tr>
            <td>Base Directory:</td>
            <td>@Html.EditorFor(model => model.Directory)</td>
            <td>@Html.ValidationMessageFor(model => model.Directory)</td>
        </tr>
        <tr>
            <td>Filename:</td>
            <td>@Html.EditorFor(model => model.Filename)</td>
            <td>@Html.ValidationMessageFor(model => model.Filename)</td>
        </tr>
    </table>
</fieldset>

which corresponds to this ViewModel

public class FileInfo
{
    [Display(Name = "Directory")]
    [Required(ErrorMessage="Please specify the base directory where the file is located")]
    public string Directory { get; set; }
    [Display(Name = "File Name")]
    [Required(ErrorMessage = "Please specify the name of the file (Either a templated filename or the actual filename).")]
    public string Filename { get; set; }

}

What I want to do is reuse the above EditorTemplate but customise the ErrorMessage based on the context the FileInfo class is used in. I can have a standard file name eg abc.txt or a 'templated' file name eg abc_DATE.txt where DATE will be replaced with some user specified date. I want an appropriate error message in each case. In essence, the only difference should be the Annotations. (I think this the key, but am not sure how to tackle this, thus my convoluted approach!)

I have tried creating an abstract Base view model and then deriving a standard file and templated FileInfo classes. I change the declaration on the current EditorTemplate to

 `@model ESG.Web.Models.BaseFileInfo`  

and use it like

@Html.EditorFor(model => model.VolalityFile, "FileInfoEditorTemplate")` 

where model.VolalityFile is a TemplatedFileInfo. The values are correctly displayed on the Edit page, however, there is no client-side validation when fields are not correctly filled. My initial guess is that this has something to do with the abstract class definition (not having any annotations on the fields).

public abstract class BaseFileInfo
{
    public abstract string Directory { get; set; }
    public abstract string Filename { get; set; }
}

// eg of derived class
public class TemplatedFileInfo : BaseFileInfo
{
    [Display(Name = "File Name")]
    [Required(ErrorMessage = "Please specify the name of a templated file eg someFileName_DATE.csv")]
    public override string Filename { get; set; }

    [Display(Name = "Directory")]
    [Required(ErrorMessage="Please specify the base templated directory where the file is located")]
    public override string Directory { get; set; }
}

This is the only way I could think of to tackle my requirement, thus the question - How to validate ViewModels derived from an abstract class? However, if there is another more feasible way to achieve this, please advise.

Ahmad
  • 22,657
  • 9
  • 52
  • 84

1 Answers1

0

I had a similar situation where I had to change the message based the value of another property.

I made the whole validation server side and without the annotations.

Then I just added the ModelErrors this way:

ModelState.AddModelError("YourPropertyName", "The Error Message you want to show.);

It's a bit extra work and overkill maybe but it did the trick for me.

Kevin Cloet
  • 2,956
  • 1
  • 19
  • 36