質問

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 をあまり使用したことがないので、上記が正しいかどうかはまったくわかりません。

そして私のデータリポジトリクラスでは ユーザーリポジトリ.vb, 、私が使用している2つの関数は次のとおりです。

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

NewUser.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 フィールド名に変更しました。そして今、ページが送信されると、名前、ログイン、電子メールがすべて入力され、パスワードは空白になります(これは、パスワードボックスごとに予期される動作であると想定しています)が、それでも 「値 '' は無効です」 エラー。

役に立ちましたか?

解決

Response.Write コントローラー内ではビューに対して何も行われません。

エラーがあればモデルを編集ページに戻す必要があります。

ModelState.AddModelError();

リポジトリ パターンを実装し、ASP.NET MVC モデル バインディング機能などを活用する方法を示す非常に良い例があります。 オタクディナーの章 プロフェッショナル 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 フレームワークによって提供されるヘルパー メソッドの使用に基づいています。次のようなメソッドを使用していることに気づくでしょう。 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 要素と検証コントロールの識別子は同じである必要があります。

<%= 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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top