1

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

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

据我所知,我正在正确地浏览我的所有页面,直到提交,它再次显示表单但在/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 的评论,我做了以下编辑:

管理员控制器.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

新用户.aspx

<%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 的编辑,并且我已经将 Form 元素更改为 DB 字段名称(至少用于测试)。现在,当页面提交时,姓名、登录名和电子邮件都已填写,密码为空(我假设这是密码框的预期行为),但我仍然收到“值''无效”错误。

4

1 回答 1

3

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

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

ModelState.AddModelError();

在专业 ASP.NET MVC 书籍的NerdDinner 章节中有一个很好的示例,说明了如何实现存储库模式,并利用 ASP.NET MVC 模型绑定功能等。

我有一个基于 Nerd Dinner 示例的示例控制器(恐怕在 c# 中):

//
// 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.NET MVC 框架提供的 Helper 方法——你会注意到我使用的方法是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) Form 元素和 Validation 控件的标识符应该相同:

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

(你有“UserEmail”和“Email”之类的东西)

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
于 2009-09-25T13:26:56.587 回答