#c# #asp.net #asp.net-mvc #viewdata
#c# #asp.net #asp.net-mvc #viewdata
Вопрос:
Есть ли простой способ передать объект из моего представления в контроллер?
Я пытался ViewData["newPerson"]
, но это не сработало.
Session["newPerson"]
работает, но есть ли другие способы, которые более рекомендуются?
Комментарии:
1. Из представления в conttoller?! Вам необходимо переосмыслить текущую архитектуру вашего приложения.
2. Входящие данные на ваш контроллер обычно поступают через значения вашего метода действия, которые поступают из значений маршрута или опубликованных данных. Что мешает вам их использовать?
Ответ №1:
Обычно вы получаете модель в качестве параметра. У вас должны быть поля формы, которые соответствуют свойствам модели.
public class PersonViewModel
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
...
}
Тогда, по вашему мнению:
@model PersonViewModel
@using (Html.BeginForm())
{
<div class="editor-label">@Html.LabelFor( model => model.FirstName )</div>
<div class="editor-field">@Html.EditorFor( model => model.FirstName )</div>
<div class="editor-label">@Html.LabelFor( model => model.LastName )</div>
<div class="editor-field">@Html.EditorFor( model => model.LastName )</div>
...
}
Затем в действиях, соответствующих представлению, отправьте и получите модель
[HttpGet]
public ActionResult CreatePerson()
{
return View( new Person() );
}
[HttpPost]
public ActionResult CreatePerson( PersonViewModel person )
{
var person = ...create and persist a Person entity based on the view model....
return Redirect("details", new { id = person.id } );
}
Ответ №2:
Вы не должны хотеть передавать объект из вашего представления в ваш контроллер, помимо вызова действия контроллера. Если вы пытаетесь передать параметр в действие вашего контроллера, вы можете добавить значение маршрута.
Например, это передаст значение 3 в качестве параметра id в ваше действие (используя логику маршрута)
@Html.ActionLink("Home", "Details", new { id = 3 });
Ответ №3:
Вы внедряете форму? Лучше всего было бы создать новое действие на вашем контроллере, которое принимает ваш объект. У вашего контроллера был бы метод, подобный этому:
public ActionResult MyAction(Person person)
{
// your code
}
Или, если вы хотите, чтобы он отвечал на сообщения:
[HttpPost]
public ActionResult MyAction(Person person)
{
// your code
}
Тогда ваше представление вызовет действие вашего контроллера через ссылку или форму отправки. Один пример для ссылки:
@Html.ActionLink("MyContoller", "MyAction", newPerson);
Ответ №4:
У меня сложилось впечатление, что вы объявляете свой обработчик для приема параметра типа FormCollection. Они могут быть проиндексированы по тексту вашей переменной для извлечения значения. Следите за опечатками — попытка получить несуществующее значение просто возвращает пробел.
Ответ №5:
Основываясь на принятом ответе, мой ответ — это не то, что вы ищете, но, основываясь на Google (на момент написания), это ответ SO, наиболее подходящий для фактической передачи данных из представления в контроллер.
Если вы установите значение на WebViewPage<T>.ViewContext.ViewData
, к нему можно получить доступ с контроллера. Мы используем этот метод, чтобы задать тему электронного письма в представлении, которое мы визуализируем как тело HTML-сообщения электронной почты. (Этот подход позволяет нам поместить определение темы вместе с телом электронного письма и получить доступ к этой теме с контроллера, куда мы фактически отправляем электронное письмо.)
/// <summary>
/// Sends a system email containing a rendered view.
/// </summary>
public static void SendSystemEmailOfView(this Controller controller, string to, [AspMvcView] string viewName, object model, ViewDataDictionary viewData = null)
{
if (viewData == null)
{
viewData = new ViewDataDictionary();
}
var body = controller.Render(viewName, model, viewData);
object subject;
if (viewData.TryGetValue(WebViewPageExtensions.ViewDataKey_EmailSubject, out subject))
{
subject = subject as string;
}
if (subject == null)
{
subject = DefaultEmailSubject;
}
SendEmail(to, (string)subject, body, isHtml: true);
}
Примечания: 1) AspMvcViewAttribute
является аннотацией Resharper, которую вы можете опустить, если не используете Resharper. 2) controller.Render
и SendEmail
являются внешними методами (есть много ответов SO о том, как отправлять электронные письма и как вручную отображать представление в строку из контроллера.)
Наше представление выглядит следующим образом:
@model MyViewModel
@{
this.EmailSubject("Subject Here");
}
<p>
Dear Web Forms,
</p>
<p>
I'm leaving you for MVC...it's just so much more...DRY.
</p>
и .EmailSubject
это похоже на это:
public const string ViewDataKey_EmailSubject = "MyAppName_EmailSubject";
/// <summary>
/// Sets an email subject in <paramref name="page"/>'s <see cref="WebViewPage{T}.ViewBag"/>. Useful for retrieving the subject from controller.
/// </summary>
public static void EmailSubject<T>(this WebViewPage<T> page, string subject)
{
// Must set value on ViewContext's ViewData if we want to access it after view renders; page.ViewData setter copies the ViewDataDictionary.
page.ViewContext.ViewData[ViewDataKey_EmailSubject] = subject;
}