【问题标题】:Passing Parameters from textboxes in a view to a controller in ASP.Net MVC2将参数从视图中的文本框传递到 ASP.Net MVC2 中的控制器
【发布时间】:2010-11-25 22:56:07
【问题描述】:

我正在通过构建一个小型示例网站来试用 ASP.Net MVC2,该网站除其他功能外,还为用户提供了“联系我们”页面。这个想法是允许用户输入他们的姓名、电子邮件地址、消息主题和消息。要发送消息,用户单击 ActionLink。这是视图:

    <% Html.BeginForm(); %>
<div>
    <%: Html.Label("Name")%>
    <br />
    <%: Html.TextBox("txtName", "",new { style = "width:100%" })%>
    <br />
    <%: Html.Label("Email address")%>
    <br />
    <%: Html.TextBox("txtEmail", "", new { style = "width:100%" })%>
    <br />
    <%: Html.Label("Subject")%>
    <br />
    <%: Html.TextBox("txtSubject", "", new { style = "width:100%" })%>
    <br />
    <%: Html.Label("Message")%>
    <br />
    <%: Html.TextBox("txtMessage", "", new { style = "width:100%" })%>
</div>
<div style='text-align: right;'>
    <%: 
        Html.ActionLink("Send", "SentEmail", new { name = Html.g, sender = "txtEmail", subject = "txtSubject", message="txtMessage" })
    %>      
</div>
<% Html.EndForm(); %>

这个想法是,一旦单击 ActionLink,就会调用控制器中的一个方法,用户名、电子邮件地址、主题和消息将被传递到该方法中。这是控制器中的方法:

        public ActionResult SentEmail(string name, string sender, string subject, string message)
    {
        //Send email here and then display message contents to user.
        ViewData["Name"] = name;
        ViewData["Message"] = message;
        ViewData["ThankyouMessage"] = "Thank you for contacting us. We will be in touch as soon as possible.";
        return View();
    }

但是...当我单击链接时,传递给该方法的值为空。我曾尝试创建一条路线来执行此操作,但它也不起作用。我应该使用其他方法吗?

谢谢,

莫里斯

【问题讨论】:

    标签: asp.net-mvc-2 parameter-passing actionlink


    【解决方案1】:

    实际上实现您想要的比在您的示例中更容易。从未听说过模型类、模型绑定器和强类型视图?这里有

    模型类

    public class ContactUsModel
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Subject { get; set; }
        public string Message { get; set; }
    }
    

    然后在你的控制器中你应该有两个动作:第一个显示带有默认值的表单,第二个接收带有用户放置的数据的表单。这两个动作完全映射到 HttpGet 和 HttPost 动词。

    [HttpGet]
    public virtual ActionResult ContactUs() {
        ContactUsModel model = new ContactUsModel();
        return View(model);
    }
    
    
    [HttpPost]
    public virtual ActionResult ContactUs( ContactUsModel model ) {
        //e.g. Save the contact request to database
    }
    

    要使用这个,你的视图应该是强类型到 ContactUsModel

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactUsModel>" %>
    
    <% using (Html.BeginForm()) { %>
        <div>
            <%: Html.LabelFor(model => model.Name) %><br />
            <%: Html.TextBoxFor(model => model.Name, new { style = "width:100%" })%>
        </div>
        <div>
            <%: Html.LabelFor(model => model.Email) %><br />
            <%: Html.TextBoxFor(model => model.EMail, new { style = "width:100%" })%>
        </div>
        <div>
            <%: Html.LabelFor(model => model.Subject) %><br />
            <%: Html.TextBoxFor(model => model.Subject, new { style = "width:100%" })%>
        </div>
        <div>
            <%: Html.LabelFor(model => model.Message) %><br />
            <%: Html.TextAreaFor(model => model.Message, new { style = "width:100%" })%>
        </div>
        <div>
            <input type="submit" value="Save" />
        </div>
    <% } %>
    

    这就是所谓的 ModelBinder 的神奇之处。请阅读更多关于 MVC 的内容here

    【讨论】:

    • 感谢 Lorenzo 的完整解释,真的很棒。我刚刚开始使用这个
    【解决方案2】:

    操作链接不会触发 http 发布,也不会传递表单字段的值,只是一个 http 获取而不传递任何表单数据 - 理想情况下,您会使用输入提交按钮发布数据。可以肯定的是,任何导致创建/更新数据的请求都应通过 http post 完成。

    提交按钮就像。

    <input type="submit" value="Send" />
    

    然后你有几种访问表单数据的方法,首先你可以使用 FormCollection 来访问数据

    [HttpPost]
    public ActionResult SendEmail(FormCollection collection)
    {
        string email = collection["txtEmail"];
        ...
    }
    

    其次,您可以使用方法参数并依赖模型绑定,但您必须确保字段名称与参数名称匹配

    <%: Html.TextBox("txtEmail", "", new { style = "width:100%" })%>
    

    ...需要...

    [HttpPost]
    public ActionResult SendEmail(string txtEmail)
    {
        ...
    }
    

    如果此表单未发布到返回视图的相同操作,那么您还需要更改您的开始表单标签,理想情况下您也应该使用“使用”。所以你会得到:

    <% using (Html.BeginForm("SendEmail", "<controller-name>"))
       { %>
    .... form fields in here ...
    <input type="submit" value="Send" />
    <% } %>
    

    如果按钮不适合您的设计,您可以使用以下内容:

    <input type="image" src="<%: Url.Content("~/Content/images/myimage.gif") %>" value="Send" />
    

    这将具有相同的效果。要从 a 标签触发帖子,尽管您需要查看使用 javascript,但我不记得确切的语法,但我想如果您使用 jquery,您会看到类似的东西:(形成一个单一的形式仅页面)

    <a href="#" click="$('form').submit(); return false;">Send</a>
    

    但是随后您创建了对 javascript 的依赖项,实际上您应该尝试让您的网站优雅地降级,以便禁用 javascript 的访问者可以使用它。在满足设计要求的同时,可能有更高级的方法来实现这一点,但这可能会严重影响客户端代码,这可能超出了您对示例的要求。

    【讨论】:

    • 我应该提到访问表单数据的方式,您可以创建一个类来充当表单数据的强类型容器 - 从长远来看,这样的视图模型是最好的方式。而且模型绑定在mvc中非常强大。
    • 感谢马克的帮助,非常感谢。你的解释非常好,帮助我更多地了解它是如何工作的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多