如何将强类型结果传递回ActionResult?

时间:2010-06-11 17:43:02

标签: asp.net asp.net-mvc-2

我有一个强类型的视图:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MPKwithMVC.Models.SmartFormViewModel>" %> 

很好地生成视图,但是当我发布时,我定义了一个ActionResult:

[AcceptVerbs(HttpVerbs.Post)]  
public ActionResult Next(MPKwithMVC.Models.SmartFormViewModel model)   
{ .. }  

当我点击下一个按钮时,我会想到它会被击中(如果我将参数更改为FormsCollection,它会起作用)。我改为收到一条消息“没有为此对象定义无参数构造函数”。

我做错了什么?

我的SmartFormsViewModel是:

    [Serializable]
public class SmartFormViewModel
{
    public List<Question> Questions { get;  set; }
    public List<Answer> Answers { get;  set; }

    public SmartFormViewModel(List<Question> questions, List<Answer> answers)
    {
        this.Questions = questions;
        this.Answers = answers;
    }

    public SmartFormViewModel()
    {
    }
}

这是视图:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MPKwithMVC.Models.SmartFormViewModel>" %>
<%@ Import Namespace="MPKwithMVC.Models" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    SmartForms
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>
        Questionaire</h2>
    <% using (Html.BeginForm("Next", "SmartForms"))
       { %>
    <div style="float: left; margin-right: 2em;">
        <% Html.RenderPartial("NavigationPanel", Model); %>
    </div>
    <div>
        <table>
            <%
                foreach (Question question in (Model.Questions))
                { %>
            <tr>
                <td>
                    <div style="text-align: right; width: 20em;">
                        <%= Html.Encode(question.QuestionText)%>
                    </div>
                </td>
                <td>
                    <div style="float: left;">
                        <% if (question.QuestionType == 1)
                           { %>
                        <%= Html.TextBoxFor(model => model.Answers[(int)question.QuestionID - 1].AnswerValue) %>
                        <% } %>
                        <% if (question.QuestionType == 2)
                           { %>
                        <%= Html.RadioButton("yn" + question.QuestionID, "Yes", false)%>Yes
                        <%= Html.RadioButton("yn" + question.QuestionID, "No", true)%>No
                        <% } %>
                    </div>
                    <% if (question.Required == true)
                       { %>
                    <div style="color: Red; float: right; margin-left: 3px;">
                        *</div>
                    <% } %>
                </td>
            </tr>
            <%
                } %>
            <tr>
                <td>
                    <%
           if (ViewData["errorMsg"] != null)
                       {%>
                       <div style="color:Red;">
                        <%= Html.Encode(ViewData["errorMsg"].ToString()) %>
                       </div>
                    <% } %>
                </td>
                <td>
                    <div style="margin-top: 1em;">

                        <button name="button" value="next">Next</button>

                    </div>
                </td>
            </tr>
        </table>
    </div>
    <% } %>

</asp:Content>

3 个答案:

答案 0 :(得分:1)

正如错误消息所示,您的SmartFormViewModel类需要包含无参数构造函数。

This是您想要做的一个很好的例子

我还建议您使用Html扩展中的强类型帮助程序来生成表单字段。

e.g。

Html.HiddenFor(x => x.SomeField) 
Html.TextBoxFor(x => x.SomeEditableField)

答案 1 :(得分:1)

确保<form>的{​​{1}}指向action方法。

答案 2 :(得分:1)

查看HTML中生成的输入名称。我认为您的控件命名存在问题,因此默认模型绑定失败,因为您提到使用FormCollection正常工作。我正在做这个假设,因为我不知道你的问题和答案类是什么样的

<%= Html.TextBoxFor(model => 
        model.Answers[(int)question.QuestionID - 1].AnswerValue) %>

这不会呈现类似于以下内容的东西;如果我没有弄错,那将不会绑定到你的模型。这同样适用于RadioButtons

<input type="text" name="Answers[0].AnswerValue" id="Answers_0__AnswerValue" value="somevalues"/>

RadioButton助手应该是

<%= Html.RadioButton("Questions[" + question.QuestionID + "].ID", "Yes", false)%> // you now get a list of questions

<input type="radio" name="Questions[1].ID" id="Questions_1__ID" value="No" checked="checked"/>

有一些方法可以尝试解决此问题:

  1. 正确命名输入控件,使它们与ViewModel匹配。 (这包括回发模型的所有必填字段 - 我认为如果未发布模型绑定,则使用默认值)
  2. 创建自定义模型装订器
  3. 您可能需要告诉Binder输入字段的前缀是什么。 ([Bind] attribute)专门包含或排除表单字段。
  4. 创建一个包含您希望回发的值的新模型
  5. 我认为总体而言,您的方法需要略微改变。根据提供的信息,您的Q&amp; As密切相关。根据问题类型,您的“答案”可以是布尔值或自由文本。目前您还没有将List<Questions>发回服务器。答案,是的,但他们不是我不认为它被认为是List<Answers>

    Haacked有一个我认为与您的问题相关的帖子,this SO question进一步表明它可能仍然适用于ASP-MVC-2。