1

I have a controller which take a model as parameter. This model is a specialized version of a generic model. I want my specialized model to hide a required base field to make it not required.

Here is what I did :

Controller

public class TestController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View(new SpecializedModel());
    }

    [HttpPost]
    public ActionResult Index(SpecializedModel model)
    {
        if(ModelState.IsValid)
        {
            //Do some stuff, eventually redirect elsewhere
        }

        return View(model);
    }
}

GenericModel

public class GenericModel
{
    [Required(ErrorMessage = "The field is required.")]
    public string SomeValue { get; set; }
}

SpecializedModel

public class SpecializedModel : GenericModel
{
    new public string SomeValue { get; set; }
}

View

    <form method="post">
        @Html.TextBoxFor(model => model.SomeValue)<br />
        @Html.ValidationMessageFor(model => model.SomeValue)<br />
        <input type="submit" />
    </form>

When I validate the form, the error message

The field is required.

is shown. I gather the RequiredAttribute is kept... is there a way to get rid of it ?

Edit : I also tried to make the SomeValue a virtual field to override it, but the problem is the same.

gobes
  • 507
  • 7
  • 25
  • Refer this as you are trying to Inherit Model, https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application – Gaurav P Jun 06 '17 at 12:39
  • If you had defined `SomeValue` in `GenericModel`, why it is required again define it in other Model i.e. `SpecializedModel` – Gaurav P Jun 06 '17 at 12:42
  • @GauravKP I don't try to inherit `Model` - what I have here is some kind of ViewModel. And `SomeValue` is "defined" in `SpecializedModel` to override it. – gobes Jun 06 '17 at 12:51
  • are you trying to omit "SomeValue" Validation error – hasan Jun 06 '17 at 12:57
  • @gobes EF is designed to bind Model Annotations with Table Columns, so if you want to follow EF you need to skip Duplicate Columns in Inherited Model i.e. `SpecializedModel` Now if your need is a View Model (for which Table doesn't exist in database), try to handle in custom way by removing `ValidationMessageFor` – Gaurav P Jun 06 '17 at 13:06
  • @GauravKP I don't make any use of EF here. – gobes Jun 06 '17 at 13:24

2 Answers2

0

Remove this line from your view

@Html.ValidationMessageFor(model => model.SomeValue)

Reshma
  • 436
  • 3
  • 13
  • That's... a simplistic answer. I've put the ValidationMessage for my tests, the real controller code has a `if(ModelState.IsValid)` statement. – gobes Jun 06 '17 at 12:44
0

So is your underlying problem that you have attributes/properties/fields on a domain object that you don't want on a domain object elsewhere in your code?

This is why libraries such as AutoMapper or other mappers exist (or even writing it yourself, but that is time consuming and repetitive).

You should have a domain object per domain layer (UI, business logic, data store) and each domain layer should have no references to each others domain object. Instead, you'd use a Data Transfer Object (DTO) to map values between the layers.

user9993
  • 5,833
  • 11
  • 56
  • 117