Pregunta

Tengo un formulario en mi aplicación MVC que en teoría debería enviar datos de vuelta a mi base de datos utilizando una clase de repositorio.

Sin embargo, cuando envíe el formulario ( http: // localhost: 1028 / admin / NewUser / ), la URL cambia a la forma en que debe someterse a, que está bien ( http: // localhost:. 1028 / admin / NewUser / enviar ), pero una vez que se ha presentado, se debe enviar al usuario a una página de confirmación

Por lo que puedo decir, me estoy moviendo a través de todas mis páginas correctamente hasta que se llega al entregar, si se muestra el formulario de nuevo, pero en / Admin / NewUser / Enviar y los datos se no se inserta en la base de datos.

Este es el ActionResult que estoy usando:

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

Soy bastante nuevo a MVC así que no estoy del todo seguro de si lo anterior es correcto o no.

Y en mi clase de repositorio de datos UserRepository.vb , las dos funciones que estoy usando son:

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

y

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

Y la forma que he creado es:

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

El código no produce ningún error, sino también no parece ser la presentación de la base de datos. Así que no estoy del todo seguro de dónde he ido mal.

Podría ser obvio para alguien con más experiencia, pero realmente no tienen ni idea en este caso.

¿Es este mi código que está causando el problema o alguna otra falla?

Gracias de antemano por cualquier ayuda.


EDIT: Basado en Zhaph - Ben Duguid comentario, he hecho las siguientes modificaciones:

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

Lo que ahora produce un error de El valor '' no es válido. para mí.

¿Quiere esto decir que los valores de formulario no se pasan correctamente al controlador?


EDIT: He hecho esas ediciones en respuesta Zhaph - edición de Ben Duguid y he cambiado los elementos de formulario a los nombres de los campos de base de datos (para la prueba por lo menos). Y ahora, cuando se envía la página, nombre de usuario y correo electrónico están todos llenos, la contraseña está en blanco (que estoy suponiendo que es el comportamiento esperado según cuadros de contraseña) pero sigue recibiendo el "El valor '' no es válido" de error.

¿Fue útil?

Solución

Response.Write en su controlador no va a hacer nada a la vista.

Usted debe devolver su modelo de nuevo a la página de edición, con cualquier error en

ModelState.AddModelError();

Hay un muy buen ejemplo de cómo se puede implementar un patrón de repositorio, y aprovechar el modelo de ASP.NET MVC características de unión, etc en el NerdDinner Capítulo del libro ASP.NET MVC profesional.

Un controlador de ejemplo que tienen (en C # temo) en base a las muestras Nerd Cena:

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

Así se puede ver que regrese el modelo de nuevo a la vista principal si hay un error, para poblar el resumen de validación.

La parte pertinente de la vista es:

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

Editar en respuesta a la pregunta editar

Lo siento, debería haber aclarado:

Mucho de esto se basa en el uso de los métodos de ayuda que ofrece el marco ASP.NET MVC - se dará cuenta de que estoy usando métodos como Html.TextBox para generar mis campos, con su nombre / ID retirado del propio modelo . De esta manera, si me carga la vista con ModelErrors en el ModelState, el ayudante se sumarán los detalles pertinentes a HTML procesado para incluir el siguiente margen de ganancia

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

La otra opción que podría tener sería añadir un mensaje a la colección ViewData, y si tiene un valor, mostrar que, en su opinión.


Editar en respuesta a la pregunta editar

Un par de cosas a tener en cuenta:

1) los identificadores de los elementos de forma y los controles de validación debe ser el mismo:

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

(que tiene cosas como "USEREMAIL" y "Enviar")

2) Usted debe devolver el hdUser a la vista en caso de error - a fin de tratar algo como esto:

<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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top