Как автоматически заполнить определенные поля при использовании @ Html.EditorForModel () для создания формы? - PullRequest
0 голосов
/ 15 февраля 2012

У меня есть пользователи, которые заполняют информацию своего профиля где-то на моем сайте, используя AspNetSqlProfileProvider, поставляемый с IDE.

Я разрешаю своим пользователям редактировать свой профиль в любое время, перейдя на страницу редактирования профиля, где автоматически заполняется форма для редактирования их профиля. В настоящее время я делаю это с помощью ViewBag для отправки каждой отдельной части профиля пользователя из моего контроллера в представление (адрес и город, например):

Контроллер получить:

ViewBag.address = CustomProfile.GetUserProfile(User.Identity.Name).Address;
ViewBag.city = CustomProfile.GetUserProfile(User.Identity.Name).City;

Вид:

    <div class="editor-field">
        @Html.TextBox("Address", (string)ViewBag.address)
    </div>

    <div class="editor-field">
        @Html.TextBox("City", (string)ViewBag.city)
    </div>

Пост контроллера:

    public ActionResult ChangeProfile( FormCollection favorites )
    {
        CustomProfile profile = CustomProfile.GetUserProfile();
        profile.Address = favorites["Address"];
        profile.City = favorites["City"];
        profile.Save();
        return RedirectToAction("Profile");
    }

Вышеописанное прекрасно работает для редактирования профилей, оно очень плавное с точки зрения моего пользователя (хотя из чтения вопросов / ответов в Интернете выясняется, что я должен использовать ViewModel, не совсем уверенный в том, как сделать переход, - произошел сбой) ,

Когда мой пользователь заходит на «оформление заказа» с веб-сайта (он совершает покупки), ему предоставляется экран, который позволяет ему вводить окончательную информацию, которая позволяет ему совершить покупку. Давайте назовем это «Страница заказа». Эти данные включают в себя имя, адрес, данные кредитной карты и т. Д. Некоторые из этих элементов информации совпадают с информацией на странице профиля веб-сайта.

Я хочу иметь возможность автоматически заполнять некоторые детали на этой странице заказа (имя, адрес), оставляя некоторые поля пустыми (кредитная карта - поэтому пользователь должен заполнять эти данные каждый раз, когда они посещают страница заказа).

Как работает страница заказа, как описано в MVC Store Tutorial . Когда отображается страница заказа, она отображает форму, используя:

@Html.EditorForModel()

Это замечательно и позволяет вам редактировать детали, указанные в модели Заказа, и позволяет проводить проверку данных (требуется имя, адрес, номера кредитной карты, правильный формат электронной почты и т. Д.), но я не могу понять, как заполнить определенные поля на этой странице заказа данными из профиля моего пользователя.

Я попытался создать новую ViewModel, которая использует только информацию, содержащуюся в моем профиле, но я не имею четкого представления о том, что необходимо, потому что я не получаю желаемый конечный результат.

Я решил использовать только модель заказа в качестве информации своего профиля, но этого недостаточно, потому что я хочу, чтобы в обоих случаях была доступна другая информация.

Я рассмотрел возможность использования информации профиля в качестве модели заказа, но я хочу, чтобы мои пользователи имели возможность хранить информацию профиля отдельно от той информации, которую они используют для фактического размещения заказов.

Я думаю, что мне нужно знать конкретно, чтобы решить мою проблему: как мне автоматически заполнить определенные поля при использовании "@ Html.EditorForModel ()"?

Любая другая помощь в моей общей ситуации была бы отличной, я очень открыт для любых советов, которые упростили бы мой поток (такое ощущение, что я усложняю себе, чем мне нужно, и я нахожусь в точке, где сотрудничество будет ощущаться как глоток свежего воздуха).

1 Ответ

3 голосов
/ 15 февраля 2012

Мне удалось проследить только первую половину вашего вопроса. Это тот, в котором вы показали некоторый код, и тот, в котором я могу вам помочь. Вторая половина была для меня полным туманом.

Поэтому, когда вы хотите создать представление, подумайте о том, какие поля необходимо отображать / редактировать. И создайте для него модель вида:

public class ChangeProfileViewModel
{
    [Required]
    public string Address { get; set; }

    [Required]
    public string City { get; set; }
}

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

public ActionResult ChangeProfile()
{
    CustomProfile profile = CustomProfile.GetUserProfile(User.Identity.Name);
    ChangeProfileViewModel model = new ChangeProfileViewModel
    {
        Address = profile.Address,
        City = profile.City
    };
    return View(model);
}

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

@model ChangeProfileViewModel
@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <button type="submit">OK</button>
}

и, наконец, у вас есть действие контроллера POST, которое будет обрабатывать отправку этой формы:

[HttpPost]
public ActionResult ChangeProfile(ChangeProfileViewModel model)
{
    if (!Model.IsValid)
    {
        // there were validation errors => redisplay the view
        return View(model);
    }

    // validation succeeded => process the results
    CustomProfile profile = CustomProfile.GetUserProfile();
    profile.Address = model.Address;
    profile.City = model.City;
    profile.Save();
    return RedirectToAction("Profile");
}

Теперь мы наблюдаем, что в наших действиях GET и POST мы имеем повторяющийся код отображения между нашей моделью предметной области (CustomProfile) и моделью представления (ChangeProfileViewModel). Для решения этой проблемы я могу порекомендовать вам использовать AutoMapper . Это может упростить ваше действие GET до:

public ActionResult ChangeProfile()
{
    CustomProfile profile = CustomProfile.GetUserProfile(User.Identity.Name);
    ChangeProfileViewModel model = Mapper.Map<CustomProfile, ChangeProfileViewModel>(profile);
    return View(model);
}

или с настраиваемым фильтром действий до четного:

[AutoMap(typeof(CustomProfile), typeof(ChangeProfileViewModel))]
public ActionResult ChangeProfile()
{
    CustomProfile profile = CustomProfile.GetUserProfile(User.Identity.Name);
    return View(profile);
}

и ваше действие POST:

[HttpPost]
public ActionResult ChangeProfile(ChangeProfileViewModel model)
{
    if (!Model.IsValid)
    {
        // there were validation errors => redisplay the view
        return View(model);
    }

    // validation succeeded => process the results
    CustomProfile profile = CustomProfile.GetUserProfile();
    Mapper.Map<ChangeProfileViewModel, CustomProfile>(model, profile);
    profile.Save();
    return RedirectToAction("Profile");
}

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

...