代码之家  ›  专栏  ›  技术社区  ›  LiamGu

表单未提交,MVC未产生任何错误

  •  1
  • LiamGu  · 技术社区  · 16 年前

    我的MVC应用程序中有一个表单,理论上应该使用Repository类将数据提交回数据库。

    但是,当我提交表格时( http://localhost:1028/Admin/NewUser/ ),URL将更改为表单应提交到的位置,这很好( http://localhost:1028/Admin/NewUser/Submit ),但一旦提交,它应将用户发送到确认页面。

    据我所知,我正在正确地浏览我的所有页面,直到它到达提交页面,在那里它再次显示表单,但在下面 并且数据不会插入到数据库中。

    这是我正在使用的ActionResult:

    Public Function Submit() As ActionResult
             Try
                Dim user = New hdUser() With { _
                    .userLogon = Request.Form("UserLogin"), _
                    .userPass = Request.Form("UserPassword"), _
                    .userEmail = Request.Form("UserEmail"), _
                    .RealName = Request.Form("UserFullName"), _
                    .isLive = 1, _
                    .avatar = "noavatar.gif" _
                 }
                userRepository.Add(user)
                userRepository.Save()
    
                Return Redirect("/Admin/NewUser/Confirm")
            Catch ex As Exception
                ModelState.AddModelError("Error", ex)
            End Try
            Return View()
        End Function
    

    我是MVC的新手,所以我不能完全确定上面的说法是否正确。

    在我的数据存储库类中 UserRepository.vb ,我使用的两个函数是:

    Public Sub Add(ByVal user As hdUser) Implements IUserRepository.Add
                db.hdUsers.InsertOnSubmit(user)
            End Sub
    

    Public Sub Save() Implements IUserRepository.Save
                db.SubmitChanges()
            End Sub
    

    我创建的表单是:

    <form action="/Admin/NewUser/Submit" method="post">
                    <table border="0" cellpadding="0" cellspacing="2">
                        <tr>
                            <td><strong>User's Full Name</strong> <br />
                             <%=Html.TextBox("UserFullName")%>
                                </td>
                        </tr>
                        <tr>
                            <td><strong>User Login</strong> <br />
                             <%=Html.TextBox("UserLogin")%>
                                </td>
                        </tr>
                        <tr>
                            <td><strong>Password</strong> <br />
                             <%=Html.Password("UserPassword")%>
                               </td>
                        </tr>
                        <tr>
                            <td><strong>Email Address</strong> <br />
                             <%=Html.TextBox("UserEmail")%>
                             </td>
                        </tr>
                        <tr>
                            <td align="right"><input type="submit" value="Create" /></td>
                        </tr>
                    </table>
            </form>
    

    代码不会产生任何错误,但似乎也没有提交到数据库。所以我不完全确定我错在哪里了。

    这对更有经验的人来说可能是显而易见的,但我对这一点真的一无所知。

    是我的代码导致了问题还是其他故障?

    提前感谢您的帮助。


    编辑: 根据Zhaph-Ben Duguid的评论,我做了以下编辑:

    AdminController.vb

    <AcceptVerbs(HttpVerbs.Post)> _
        Public Function NewUser(ByVal formValues As FormCollection) As ActionResult
            Try
                Dim user = New hdUser()
                user.userLogon = Request.Form("UserLogin")
                user.userPass = Request.Form("UserPassword")
                user.userEmail = Request.Form("UserEmail")
                user.RealName = Request.Form("UserFullName")
                user.isLive = 1
                user.avatar = "noavatar.gif"
                UpdateModel(user)
                userRepository.Add(user)
                userRepository.Save()
            Catch ex As Exception
                ModelState.AddModelError("Error", ex)
            End Try
            Return View()
        End Function
    

    <%Html.BeginForm()%>
                <%=Html.ValidationMessage("Error")%>
                      <table border="0" cellpadding="0" cellspacing="2">
                        <tr>
                            <td><strong>User's Full Name</strong> <br />
                             <%=Html.TextBox("UserFullName")%>
                                <%=Html.ValidationMessage("Name", "*")%></td>
                        </tr>
                        <tr>
                            <td><strong>User Login</strong> <br />
                             <%=Html.TextBox("UserLogin")%>
                                <%=Html.ValidationMessage("Username", "*")%></td>
                        </tr>
                        <tr>
                            <td><strong>Password</strong> <br />
                             <%=Html.Password("UserPassword")%>
                                <%=Html.ValidationMessage("Password", "*")%></td>
                        </tr>
                        <tr>
                            <td><strong>Email Address</strong> <br />
                             <%=Html.TextBox("UserEmail")%>
                             <%=Html.ValidationMessage("Email", "*")%></td>
                        </tr>
                        <tr>
                            <td align="right"><input type="submit" value="Create" /></td>
                        </tr>
                    </table>
                    <% Html.EndForm() %>
    

    现在产生的错误为 值“”无效。 为了我。

    这是否意味着表单值没有正确地传递给控制器?


    编辑: 为了响应Zhaph-Ben Duguid的编辑,我做了这些编辑,并将表单元素更改为DB字段名(至少用于测试)。现在,当提交页面时,名称、登录名和电子邮件都已填写,密码为空(我假设这是密码框的预期行为),但我仍然收到 值“”无效 错误

    1 回复  |  直到 13 年前
        1
  •  3
  •   Zhaph - Ben Duguid    16 年前

    Response.Write 在您的控制器中,它不会对视图做任何事情。

    您应该将模型返回到“编辑”页面,其中有任何错误

    ModelState.AddModelError();
    

    这里有一个非常好的示例,说明了如何实现存储库模式,以及如何利用中的ASP.NET MVC模型绑定功能等 NerdDinner Chapter 来自专业的ASP.NETMVC书籍。

    //
    // POST: /AdminAlbums/Create
    
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(FormCollection collection)
    {
      var album = new Album();
    
      // Method on System.Web.Mvc.Controller, that takes a form collection, and
      // using reflection on the Model, assigns values to it from the form.
      UpdateModel(album);
    
      if (album.IsValid)
      {
        // These methods are the same as yours
        m_PhotoRepository.Add(album);
        m_PhotoRepository.Save();
    
        // In this instance, I'm returning the user to a list view of Albums
        // for editing, probably ought to send them to the page to start 
        // uploading photos.
        return RedirectToAction("Index");
      }
    
      // Still here, so I'm going to set up some ViewData I need.
      ViewData["Title"] = "Create a new album";
      ViewData["Message"] = "Create Album";
    
      // I'm picking up errors from the model here.
      // RuleViolation is my own class, implemented in a partial on Album.
      foreach (RuleViolation violation in album.GetRuleViolations())
      {
        ModelState.AddModelError(violation.PropertyName, violation.ErrorMessage);
      }
    
      return View(album);
    }
    

    因此,您可以看到,如果出现错误,我会将模型返回到主视图,以填充验证摘要。

    该观点的相关部分是:

    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
    <% using (Html.BeginForm()) {%>
      <fieldset>
        <legend>Album details</legend>
        <div class="form_row">
          <label for="Caption" class="left_label">Album caption:</label>
          <%= Html.TextBox("Caption", Model.Caption, new { @class = "textbox" })%>
          <%= Html.ValidationMessage("Caption", "*") %>
          <div class="cleaner">&nbsp;</div>
        </div>
        <div class="form_row">
          <label for="IsPublic" class="left_label">Is this album public:</label>
          <%= Html.CheckBox("IsPublic", Model.IsPublic) %>
        </div>
        <div class="form_row">
          <input type="submit" value="Save" />
        </div>
      </fieldset>
    <% } %>
    

    对不起,我应该澄清一下:

    这其中很多都是基于使用ASP.NETMVC框架提供的助手方法——您会注意到我使用的方法如下 Html.TextBox 要生成我的字段,请使用从模型本身提取的名称/id。这样,如果在ModelState中加载带有ModelErrors的视图,助手将向呈现的HTML添加相关细节,以包括以下标记

    <label for="Caption" class="left_label">Caption:</label>
    <input class="input-validation-error textbox" 
           id="Caption" name="Caption" type="text" value="" />
    <span class="field-validation-error">*</span>
    

    您可以选择的另一个选项是将消息添加到 ViewData 集合,如果它有值,则在视图上显示该值。


    要记住以下几点:

    1) 表单元素和验证控件的标识符应相同:

    <%= Html.TextBox("Caption", Model.Caption, new { @class = "textbox" })%>
    <%= Html.ValidationMessage("Caption", "*") %>
    

    (你有“用户电子邮件”和“电子邮件”之类的东西)

    2) 您应该在出错时将hdUser返回到视图-因此请尝试以下操作:

    <AcceptVerbs(HttpVerbs.Post)> _
    Public Function NewUser(ByVal formValues As FormCollection) As ActionResult
      Dim user = New hdUser()
      Try
        UpdateModel(user)
        user.isLive = 1
        user.avatar = "noavatar.gif"
    
        userRepository.Add(user)
        userRepository.Save()
      Catch ex As Exception
          ModelState.AddModelError("Error", ex)
      End Try
      Return View(user)
    End Function