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

У меня есть пользователи, которые заполняют информацию своего профиля где-то на моем сайте, используя 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. Когда отображается страница заказа, она отображает форму, используя:

@Html.EditorForModel()

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

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

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

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

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

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

1 ответ

Решение

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

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

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

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

Другие вопросы по тегам