Как автоматически заполнить определенные поля при использовании @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");
}
Что важно знать о моделях представлений, так это то, что вы всегда должны использовать их для каждого представления и разрабатывать их таким образом, чтобы они содержали только конкретную информацию, которая должна обрабатываться этим представлением. Оставьте на уровне отображения обрабатывать преобразование между вашими доменными сущностями и вашими моделями представления.