Pergunta

Eu tenho um formulário em meu aplicativo MVC que em teoria deveria enviar dados de volta para o meu banco de dados usando uma classe Repository.

No entanto, quando eu enviar o formulário ( http: // localhost: 1028 / admin / NewUser / ), o URL muda para onde o formulário deve ser submeter-se, o que é bom ( http: // localhost:. 1028 / admin / NewUser / enviar ), mas uma vez que tenha sido apresentado, ele deve enviar o usuário para uma página de confirmação

Do que eu posso dizer, eu estou movendo através de todas as minhas páginas corretamente até que se trata de apresentar, onde ele exibe o formulário novamente, mas sob / Admin / NewUser / Enviar e os dados são não inserido no banco de dados.

Este é o ActionResult que estou 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

Eu sou bastante novo para MVC, então eu não estou totalmente certo se o acima está correta ou não.

E nos meus dados de classe repositório UserRepository.vb , as duas funções que estou usando são:

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

e

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

E a forma que eu criei é:

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

O código não produz quaisquer erros, mas também não parece ser submeter-se ao banco de dados. Então, eu não sou inteiramente certo onde eu tenho errado ido.

Poderia ser óbvio para alguém mais experiente, mas eu realmente não tenho a menor idéia sobre este.

É este o meu código que está causando o problema ou alguma outra falha?

Agradecemos antecipadamente por qualquer ajuda.


EDIT: Com base Zhaph - comentário Ben Duguid, eu fiz as seguintes edições:

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

que agora produz um erro de O valor '' é inválido. para mim.

Isso significa que os valores de formulário não estão sendo passados ??corretamente para o controlador?


EDIT: Eu fiz essas edições em resposta Zhaph - edição de Ben Duguid e eu mudei os elementos de formulário para os nomes dos campos DB (para testar pelo menos). E agora, quando a página é enviada Nome, Login e-mail estão todos cheios, a senha é em branco (que eu estou supondo que é o comportamento esperado conforme caixas de senha), mas eu ainda receber a "O valor '' é inválido" erro.

Foi útil?

Solução

Response.Write em seu controlador não vai fazer nada para a vista.

Você deve estar retornando seu modelo de volta para a página de edição, com todos os erros em

ModelState.AddModelError();

Há um exemplo muito bom de como você pode implementar um padrão Repository, e tirar proveito do modelo ASP.NET MVC características de ligação, etc na NerdDinner Capítulo do livro Professional ASP.NET MVC.

Um exemplo controlador eu tenho (em c # Eu tenho medo) com base nas amostras Nerd Jantar:

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

Assim você pode ver que eu retornar o modelo de volta para a tela principal se houver um erro, para preencher o resumo de validação.

A parte relevante do ponto de vista é:

<%= 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 em resposta à pergunta de edição

Desculpe, eu deveria ter esclarecido:

Um monte de presente é baseada na utilização dos métodos auxiliares fornecidos pela estrutura ASP.NET MVC - você vai notar que eu estou usando métodos como Html.TextBox para gerar meus campos, com seu nome / id retirado do próprio modelo . Dessa forma, se eu carregar a vista com ModelErrors no ModelState, o helper irá adicionar os detalhes relevantes para HTML processado para incluir o seguinte mark-up

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

A outra opção que você poderia ter seria a de adicionar uma mensagem para a coleção ViewData, e se ele tem um valor, mostrar que em seu ponto de vista.


Editar em resposta à pergunta de edição

Um par de coisas a ter em mente:

1) Os identificadores dos elementos de formulário e os controles de validação deve ser o mesmo:

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

(você tem coisas como "USEREMAIL" e "E-mail")

2) Você deve estar retornando a hdUser à vista em caso de erro - de modo a tentar algo como isto:

<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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top