Полиморфизм и строго типизированные представления в ASP.NET MVC

У меня проблема с двумя идентичными формами, за исключением того, что обязательные поля различны. Например, предположим, что формы имеют одинаковые поля: X, Y и Z. В Форме № 1 X требуется, но в Форме № 2 требуется Y.

Поэтому я создал две модели представления, Form1 и Form2, с одинаковыми свойствами, но с обязательными атрибутами для разных свойств. Затем я создал интерфейс, назовем его IForm, который реализуют обе модели, и построил представление, строго типизированное для IForm.

Проблема с этим решением заключается в том, что ASP.NET MVC 3 считывает атрибуты в IForm вместо динамического типа объекта, передаваемого в представление, то есть Form1 или Form2, поэтому я не получаю проверку поля JavaScript на стороне клиента, которое Я хочу.

Мне интересно, есть ли другое решение, кроме создания строго типизированного представления для каждой модели представления.


person Michael    schedule 26.07.2011    source источник


Ответы (2)


Я собрал образец того, что вы описали (я думаю), и я могу заставить его работать:

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; }
}

Затем я определил строго типизированное представление:

@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>
}

Когда я перехожу к / test / foo и нажимаю «Сохранить», я получаю сообщение об ошибке проверки для имени.

Когда я просматриваю / test / bar и нажимаю «Сохранить», я получаю сообщение об ошибке проверки в описании.

person Dismissile    schedule 26.07.2011
comment
Ты прав. Проверка работает на стороне сервера. Но проверка на стороне клиента jQuery не работает, и не похоже, что есть простое решение, поэтому я помечаю его как ответ. - person Michael; 27.07.2011

Попробуйте метод частичной проверки формы.

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

Создайте атрибут фильтра настраиваемого действия. Украсьте им методы действий, чтобы игнорировать свойства проверки в соответствии с формами.

person Van Thoai Nguyen    schedule 27.07.2011