Реализация связывания модели интерфейса ASP.NET MVC 3 (с ViewModel) - PullRequest
1 голос
/ 22 апреля 2011

Я только изучаю ASP.NET MVC 3, и меня немного смущает, как я могу реализовать что-то вроде того, что показано в этой ссылке:

http://www.codethinked.com/easy-and-safe-model-binding-in-aspnet-mvc

Почему я 'м путать скорее всего основано на моем незнании предмета.В примере на странице, указанной выше, я вижу, что Джастин использует ViewModel, который напрямую содержит свойства его объекта "Person".

То, что я хочу сделать, похоже, но я хочу, чтобы ViewModel на самом деле содержал класс домена, который в моем случае является Company, а не Person.У меня есть класс Company, который сам реализует представления подмножества ViewModel (например, IEditCompanyAsUser).

То, что я пробовал до сих пор, выглядит примерно так:

public class Company : IValidatableObject, ICompanyUpdateAsUser
{
    [Key]
    [ScaffoldColumn(false)]
    public virtual int CompanyID { get; set; }

    [Required]
    public virtual Boolean Active { get; set; }

    [Required]
    public virtual string Name { get; set; }

    [Required]
    public virtual string Phone { get; set; }

    // Containing some more members below
 }

С ICompanyUpdateAsUser, содержащимСвойства Я бы хотел, чтобы метод Edit моего контроллера обновлялся:

public interface ICompanyUpdateAsUser
{
    bool Active { get; set; }
    string Name { get; set; }
    string Phone { get; set; }  
}

И класс ViewModel, который выглядит следующим образом:

public class CompanyViewModel
{
    public Company Company;
    // Will be adding more members in the future
}

Что я не могу понять, это как правильно кодироватьконтроллер.Мой контроллер в настоящее время выглядит так:

    /// <summary>
    /// POST: /Company/Edit/5
    /// </summary>
    [HttpPost]
    public ActionResult Edit([Bind(Prefix="Company")]Company model)
    {
        var company = _companyService.GetCompany(model.CompanyID);

        if (company == null)
            return RedirectToAction("Index");

        if (ModelState.IsValid)
        {
            if (TryUpdateModel<ICompanyUpdateAsUser>(company))
            {
                _companyService.SaveCompany();
                return RedirectToAction("Details", new { companyId = model.CompanyID });
            }
        }

        return View(model);
    }

Я знаю, что что-то абсолютно не так с моим кодом контроллера, но я не могу понять, какие компоненты мне нужно использовать для реализации такого шаблона?Нужно ли использовать связующее для нестандартной модели?Нужно ли использовать какую-то другую функцию ASP.NET MVC3 для реализации шаблона?

Буду признателен за любой совет.

Спасибо!

* РЕДАКТИРОВАТЬ *

То, что мне нужно сделать, это иметь сообщение "Изменить представление" назад "Компанияmsgstr "объект, затем обновите объект из базы данных значениями в опубликованной компании (в соответствии со свойствами интерфейса, переданными TryUpdateModel).Кажется, что все работает (проверка и т. Д.), Но TryUpdateModel (компания), похоже, не работает, хотя и оценивается как true.Когда я перебираю код с помощью отладчика, объект Company, извлеченный из БД, просто никогда не обновляется.

После еще большего чтения я определил, что метод TryUpdateModel обновляет переданный элемент из метода IValueProvider.Как связать переданный в «Модель компании» с IValueProvider для метода?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2011

В итоге я решил проблему, сначала сделав пару модификаций ... в моем вопросе мой контроллер не смог использовать созданный мной класс ViewModel. Однажды я изменил контроллер так, чтобы он выглядел так:

 /// <summary>
    /// POST: /Company/Edit/5
    /// </summary>
    [HttpPost]
    public ActionResult Edit(CompanyViewModel viewModel)
    {
        var company = _companyService.GetCompany(viewModel.Company.CompanyID);

        if (company == null)
            return RedirectToAction("Index");

        if (ModelState.IsValid)
        {
            if (TryUpdateModel<ICompanyUpdateAsUser>(company, "Company"))
            {
                _companyService.SaveCompany();
                return RedirectToAction("Details", new { companyId = viewModel.Company.CompanyID });
            }
        }

        return View(viewModel);
    }

Я обнаружил, что все работает нормально, но, как указано в комментариях выше, TryUpdateModel просто НЕ РАБОТАЕТ, хотя возвращает true!

Просеяв тонны переполнения стека и других сообщений на форуме, я обнаружил, что TryUpdateModel не работает с полями, а только со свойствами. Чтобы заставить его работать должным образом, мне пришлось изменить мой ViewModel, чтобы он выглядел так:

public class CompanyViewModel
{
    public Company Company { get; set; }

    public CompanyViewModel(Company company)
    {
        Company = company;
    }

    public CompanyViewModel()
    {
        Company = new Company();
    }
 }

Такая глупая ошибка, хотя я чувствую, что этот момент намного упускается из виду во многих уроках связывания моделей, которые я читал.

Надеюсь, этот ответ сэкономит кому-то время.

0 голосов
/ 22 апреля 2011

Должна быть перегрузка TryUpdateModel, которая принимает префикс. Поскольку ваша исходная модель представления содержит ваш объект Company, то имена полей формы, которые были сгенерированы для объекта Company (предполагается, что вы используете стандартные входные имена форм), содержат префикс «Company», похоже, вы узнали это по модели, используемой методом, попробуйте использовать тот же префикс при обновлении вашего доменного объекта.

К вашему сведению, как правило, не рекомендуется использовать ваши доменные объекты в вашей модели представления, основная причина этого в том, что могут быть поля, которые вы не хотите разрешать пользователю обновлять. Если пользователь обладает достаточными знаниями о вашем домене, он может добавить дополнительные поля формы в данные публикации, и MVC слепо обновит эти свойства / поля, и это может вызвать проблему. Есть способы заставить MVC исключить определенные свойства / поля при привязке, но это становится кошмаром обслуживания и обычно проще использовать отдельные объекты для ваших представлений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...