2009-09-25 6 views
1

J'ai un formulaire dans mon application MVC qui en théorie devrait soumettre des données à ma base de données en utilisant une classe Repository.Formulaire ne pas soumettre et aucune erreur n'est produite avec MVC

Cependant, lorsque je soumets la forme (http://localhost:1028/Admin/NewUser/), l'URL change à l'endroit où le formulaire doit être soumet, ce qui est bien (http://localhost:1028/Admin/NewUser/Submit), mais une fois qu'il a été soumis, il devrait envoyer à l'utilisateur à une page de confirmation. D'après ce que je peux dire, je suis en train de parcourir toutes mes pages correctement jusqu'à ce qu'il arrive à la soumission, où il affiche à nouveau le formulaire mais sous /Admin/NewUser/Submit et les données ne sont pas insérées dans le base de données.

C'est le ActionResult J'utilise:

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 

Je suis assez nouveau pour MVC donc je ne suis pas tout à fait sûr que ce qui précède est correcte ou non.

Et dans mon dépôt de données de classe UserRepository.vb, les deux fonctions que je utilise sont:

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

et

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

Et la forme que j'ai créé est:

<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> 

Le code ne produit aucune erreur mais ne semble pas non plus être soumis à la base de données. Donc, je ne suis pas tout à fait sûr où je me suis trompé.

Cela pourrait être évident pour quelqu'un plus expérimenté, mais je n'ai vraiment aucune idée sur celui-ci.

Est-ce mon code qui cause le problème ou un autre défaut?

Merci d'avance pour toute aide.


EDIT: Basé sur Zhaph - Ben Duguid commentaire, je l'ai fait les modifications suivantes:

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() %> 

Ce qui produit maintenant une erreur de La valeur '' est invalide. pour moi. Cela signifie-t-il que les valeurs de formulaire ne sont pas transmises correctement au contrôleur?


EDIT: Je ai fait ces modifications en réponse Zhaph - edit Ben Duguid et j'ai changé les éléments de formulaire pour les noms de champs DB (pour les tests au moins). Et maintenant, lorsque la page est soumise Nom, Login et Email sont tous remplis, mot de passe est vide (ce que je suppose est attendu comportement par les boîtes de mot de passe) mais je reçois toujours le "La valeur" est invalide " erreur .

+0

Où allez-vous obtenir l'erreur de? Pourriez-vous poster une trace de pile? –

+0

Ce ne sera pas jusqu'à lundi maintenant que je ne suis plus au bureau. – LiamGu

+1

Pas de problème, je vais garder;) –

Répondre

3

Response.Write dans votre contrôleur ne va rien faire à la vue.

Vous devriez retournerez votre modèle de retour à la page d'édition, avec des erreurs dans

ModelState.AddModelError(); 

Il y a un très bon exemple de la façon dont vous pouvez mettre en œuvre un modèle de référentiel, et tirer parti de la MVC ASP.NET fonctions de liaison de modèle, etc dans le NerdDinner Chapter du livre Professional ASP.NET MVC.

Un contrôleur exemple je (en C# J'ai peur) sur la base des échantillons Dîner Nerd:

// 
// 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); 
} 

Vous pouvez voir que je reviens le modèle de retour à la vue principale s'il y a une erreur, à remplir le résumé de validation.

La partie pertinente de la vue est:

<%= 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> 
<% } %> 

Modifier en réponse à la question modifier

Désolé, je aurais dû préciser:

Beaucoup de cela est basé sur l'utilisation des méthodes Helper fournies par le framework ASP.NET MVC - vous remarquerez que j'utilise des méthodes comme Html.TextBox pour générer m y fields, avec leur nom/id tiré du modèle lui-même. De cette façon, si je charge la vue avec ModelErrors dans le ModelState, l'assistant ajoutera les détails pertinents à rendu HTML pour inclure la majoration suivante

<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> 

L'autre option que vous pourriez avoir serait d'ajouter un message à la collection ViewData, et si elle a une valeur, affichez cela sur votre vue.


Modifier en réponse à la question modifier

Un couple de choses à garder à l'esprit:

1) Les identifiants des éléments de formulaire et les contrôles de validation doivent être les mêmes:

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

(vous avez des choses comme "UserEmail" et "E-mail")

2) Vous devriez être retourner le hdUser à la vue en cas d'erreur - alors essayez quelque chose comme ceci:

<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 
+0

J'ai fait une modification basée sur la dernière révision de votre commentaire. – LiamGu

+0

Le nom des éléments de formulaire doit-il être le même que celui des champs de base de données? – LiamGu