ti-enxame.com

Como habilitar manualmente a validação jQuery com o ASP.NET MVC

Estou lutando para entender alguns dos princípios básicos da validação do jQuery, conforme conectado ao ASP.NET MVC.

A versão curta desta pergunta é: Que mágica estou faltando que permite que o código produzido por @Html.EditorFor() execute a validação do jQuery, mas não funciona, tento conectar minha própria validação do jQuery usando exatamente o mesmo HTML ?

Como exercício de aprendizado (e porque imita o que realmente quero fazer no meu site), criei um novo aplicativo MVC 4 no Visual Studio 2012. Adicionei um modelo de exibição:

using System.ComponentModel.DataAnnotations;
namespace ValidationTest.Models
{
    public class MyViewModel
    {
        [Required]
        public string MyStringValue { get; set; }
    }
}

e modifiquei Views\Home\Index.cshtml para criar um formulário com base no meu modelo de exibição como este:

@model ValidationTest.Models.MyViewModel
@using (Html.BeginForm(new { id = "MyForm" })) {
    @Html.LabelFor(m => m.MyStringValue)
    @Html.EditorFor(m => m.MyStringValue)
    @Html.ValidationMessageFor(m => m.MyStringValue)

    <br />
    <input type="submit" value="Submit" />
}

Por fim, modifiquei o controlador Home para fornecer o modelo de exibição ao formulário e manipular o POST associado, assim:

using System.Web;
using System.Web.Mvc;
using ValidationTest.Models;

namespace ValidationTest.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            var viewModel = new MyViewModel();
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Index(MyViewModel viewModel)
        {
            if (!ModelState.IsValid) return View(viewModel);

            return RedirectToAction("About");
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your app description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }
}

Quando executo o projeto, a página da web exibe uma caixa de texto e valida magicamente que o usuário deve inserir um valor. Por enquanto, tudo bem...

Agora, meu aplicativo atual é uma pesquisa on-line. Ele exibe perguntas e solicita respostas com base em um script. Meu viewmodel atual contém propriedades que são mapeadas para o texto da pergunta, o valor fornecido pelo usuário etc. O viewmodel também contém uma propriedade Boolean Required que especifica se o usuário deve ou não fornecer um valor (por exemplo, se deseja ou não habilitar validação "obrigatório" na Visualização) - portanto, isso significa que preciso remover o [Required] atributo na propriedade MyStringValue no meu viewmodel e forneça minha própria mágica de validação com base na propriedade Required no viewmodel.

É aqui que eu me perco. No IE, posso ver que as chamadas @ html.xxx no aplicativo de exemplo (descritas acima) produzem este HTML para o formulário:

<label for="MyStringValue">MyStringValue</label>
<input  class="text-box single-line" 
        data-val="true" 
        data-val-required="The MyStringValue field is required." 
        id="MyStringValue" 
        name="MyStringValue" 
        type="text" 
        value="" />
<span data-valmsg-for="MyStringValue" data-valmsg-replace="true"></span>

Mas não vejo HTML em nenhum outro lugar da página que obviamente faça referência à biblioteca de validação jQuery, nem o código JavaScript que permite a validação, portanto não entendo por que isso funciona.

Além disso, se eu remover o [Required], e codifique a View para emitir o HTML acima (sem as chamadas magic @ html.xxx ()), então nenhuma validação acontece.

O que estou perdendo?

17
Bob.at.Indigo.Health

Sim, estava faltando algo realmente fundamental.

O modelo de página (_Layout.cshtml) criado para um novo projeto MVC 4 contém este código no final da página:

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>

Esse código extrai a biblioteca jQuery (depois que todo o HTML na página foi visto pelo navegador) e, em seguida, renderiza uma "seção" opcional que pode ser fornecida pela exibição. Esse código não atrai a biblioteca de validação do jQuery.

A validação do ASP.NET MVC funciona sem a validação do jQuery, mas toda a validação é feita no servidor. O observador cuidadoso observará que, uma vez avisado que um valor de string ausente deve ser fornecido, a validação do lado do cliente faz com que o aviso desapareça simplesmente inserindo um único caractere na caixa de texto ofendida. Mas, sem a validação do jQuery ativada, digitar na caixa de texto não remove o aviso dinamicamente.

Para "ativar" a validação do jQuery para uma única visualização, esse código precisa residir em algum lugar no arquivo cshtml da visualização (estilisticamente, ele deseja estar no final do arquivo, pois será exibido no final do HTML) :

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Portanto, a resposta curta para minha pergunta é adicionar o código acima no final do meu arquivo Views\Home\Index.cshtml. Isso permite a validação do jQuery, a mágica acontece e os atributos data-xxx não são mais ignorados. A vida é boa.

12
Bob.at.Indigo.Health

Não há mágica que você está perdendo. O script de 'validação discreta' da Microsoft pode ser usado em qualquer site que use jquery e jquery validate. Ele não está vinculado ao ASP.NET - desde que o HTML seja o formato esperado pelo script discreto, o script funcionará. Este violino mostra o script discreto aplicado a um formulário não produzido pelo ASP.NET .

O script discreto tem duas tarefas principais:

  1. Inicialize o plugin jquery.validate.js
  2. Leia os atributos data-val * na marcação e traduza isso em regras de validação de jquery

Como você deve ter lido , os atributos de marcação que o script discreto lê são os seguintes

data-val="true"
data-val-rulename="message"
data-val-rulename-paramname1="paramvalue"
data-val-rulename-paramname2="paramvalue"

então um campo de entrada pode ficar assim

  <input
     data-val="true" 
     data-val-required="This field is required..." 
     data-val-number="Please enter a number..."
     data-val-range="Must be between 50 and 100...",
     data-val-range-min="50"
     data-val-range-max="100"
     id="mynumber" 
     name="mynumber" 
     type="text" value="" />

Minha opinião pessoal sobre o script discreto é que ele se enquadra na categoria do que Steve Sanderson chama de 'demoware' em seu livro do MVC . Ele faz algumas coisas legais prontas para uso, mas dificulta a validação de jquery , que é muito mais fácil de usar por si só. Costumo excluí-lo quando inicio um novo projeto.

10
Dr Blowhard