查看从视图到控制器的数据

本文关键字:控制器 数据 视图 | 更新日期: 2023-09-27 17:56:13

有没有一种简单的方法可以将对象从我的视图传递到控制器?

我试过ViewData["newPerson"]但没有用。

Session["newPerson"]有效,但还有其他更推荐的方法吗?

查看从视图到控制器的数据

通常,您会收到一个模型作为参数。 您必须具有映射到模型属性的表单字段。

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

除了调用控制器的操作之外,您不应该希望将对象从视图传递到控制器。 如果尝试将参数传递给控制器操作,可以添加路由值。

例如,这会将值 3 作为 id 参数传递到您的操作中(使用路由逻辑)

@Html.ActionLink("Home", "Details", new { id = 3 });

你在实现一个表单吗? 最好的办法是在控制器上创建一个新操作来接收您的对象。 您的控制器将具有如下方法:

public ActionResult MyAction(Person person)
{
    // your code
}

或者,如果您希望它回复帖子:

[HttpPost]
public ActionResult MyAction(Person person)
{
    // your code
}

然后,您的视图将通过链接或表单提交调用控制器操作。 链接的一个示例:

@Html.ActionLink("MyContoller", "MyAction", newPerson);

我的印象是,你声明你的处理程序来接受 FormCollection 类型的参数。 可以通过变量的文本对其进行索引以检索值。 注意拼写错误 - 尝试检索不存在的值只会返回一个空白。

根据公认的答案,我的答案不是您要找的,但基于 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.RenderSendEmail是外部方法(关于如何发送电子邮件以及如何从控制器内手动将视图呈现为字符串,有许多 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;
}