0

I have a problem where I have two forms that are identical except that the required fields are different. For example, let's say the forms have the same fields: X, Y, and Z. In Form #1, X is required, but in Form #2, Y is required.

So I created two view models, Form1 and Form2, with the same properties but with the Required attributes on different properties. I then created an interface, let's call it IForm, that both models implement and built a View that is strongly typed on IForm.

The problem with that solution is that ASP.NET MVC 3 reads the attributes on IForm instead of the dynamic type of the object being passed to the view, that is Form1 or Form2, so I don't get the client side JavaScript field validation that I want.

I'm wondering if there's a solution other than creating a strongly-typed View for each view model.

2 Answers 2

2

I have put together a sample with what you described (I think) and I'm able to get it to work:

public class TestController : Controller
{
    public ActionResult Foo()
    {
        return View("IFoo");
    }

    [HttpPost]
    public ActionResult Foo(Foo foo)
    {
        if (!ModelState.IsValid)
            return View("IFoo", foo);

        return RedirectToAction("Foo");
    }

    public ActionResult Bar()
    {
        return View("IFoo");
    }

    [HttpPost]
    public ActionResult Bar(Bar bar)
    {
        if (!ModelState.IsValid)
            return View("IFoo", bar);

        return RedirectToAction("Bar");
    }
}

// The Interface - the Required attributes are not 
// on the interface, just the concrete classes
public interface IFoo
{
    string Name { get; set; }
    string Description { get; set; }
}

// Concrete Class 1 - Name is required
public class Foo : IFoo
{
    [Required(ErrorMessage="Name is required.")]
    public string Name { get; set; }

    public string Description { get; set; }
}

// Concrete Class 2 - Description is required
public class Bar : IFoo
{
    public string Name { get; set; }

    [Required(ErrorMessage = "Description is required.")]
    public string Description { get; set; }
}

I then defined a strongly typed view:

@model Test.Controllers.IFoo

<h2>Test</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>IFoo</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

When I browse to /test/foo and hit the Save, I get a validation error on Name.

When I browse to /test/bar and hit the Save, I get a validation error on Description.

Sign up to request clarification or add additional context in comments.

1 Comment

You are correct. The validation works on the server side. But the jQuery client-side validation doesn't work, and it doesn't look like there's a simple solution, so I'm marking it as answered.
0

Try partial form validation approach.

http://softwaredevelopmentsolutions.blogspot.com/2011/06/aspnet-mvc-3-partial-form-validation-on.html

Create custom action filter attribute. Decorate the action methods with it to ignore validation properties according to the forms.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.