DataAnnotation validating property with Javascript plugin. ASP.NET MVC

4

I need to validate a field in my model that has a text editor in Javascript . So far so good, because the problem only occurs in the registry that I do not get in the Action parameter "Create" an object, but a FormCollection . In the case of my Edit, I get an Instantiated Object, in this case the edited object with all properties filled in and the DataAnnotation works perfectly.

I have tried to make my Create use this binding to receive in Action by parameter the object with the properties set, it works, however my ModelState.IsValid always comes false, because it has required properties that hedge within this Action, then ModelState only checks when it enters Action and does not update itself any more (I've tried TryUpdateModel() and it does not work too).

What I need is to know how to work with the FormCollection or Binding, each has its problem in my case. I'll post the case and you'll review it.

Model:

public class News
    {
        public int IdNews { get; set; }

        [DisplayName("*Título:")]
        [RegularExpression(@"^[0-9a-zA-Z\-\sãâáàéèêíìîõôóòûúùç]{1,50}$", ErrorMessage = "Apenas letras ou números são aceitos.")]
        [Required(ErrorMessage = "Defina o título.")]
        public string Title { get; set; }

        [DisplayName("*Descrição:")]
        [StringLength(5000, MinimumLength = 100, ErrorMessage = "A descrição deve conter no mínimo 100 caracteres e no máximo 5000.")]
        [Required(ErrorMessage = "Escreva a descrição.")]
        [UIHint("tinymce_jquery_full"), AllowHtml]        
        public string Description { get; set; }

        [DisplayName("*Data de postagem:")]        
        [DisplayFormat(DataFormatString = "{0: dd/MM/yyyy}")]
        public DateTime PostDate { get; set; }

        //[Required(ErrorMessage = "Escreva o nome do Administrador que esta postando.")]
        public string AdminName { get; set; }

        [DisplayName("Selecione uma imagem:")]
        public string ImagePath { get; set; }
    }

Action:

[HttpPost]
        [ValidateInput(false)]
        [ValidateAntiForgeryToken]
        public ActionResult Create(FormCollection form)
        {
            News news = new News()
            {
                Title = (form["title"] as string) ?? String.Empty,
                Description = (form["description"] as string) ?? String.Empty,
                PostDate = DateTime.Now,
                AdminName = AdminModel.UserLogged.Name ?? String.Empty,
            };

            if (ModelState.IsValid)
            {
                if (Request.Files["fileUpload"].ContentLength > 0)
                {
                    PhotoController pCon = new PhotoController();
                    news.ImagePath = pCon.NewsFile(Request.Files, news);
                }
                else
                    news.ImagePath = String.Empty;

                using (NewsDAO dao = new NewsDAO())
                {
                    if (dao.SaveNews(news))
                    {
                        ViewBag.AlertMessage = ("Notícia inserida com sucesso!");
                        return View();
                    }
                }
            }
            ViewBag.AlertMessage = "Erro ao inserir notícia.";
            return View(news);
        }

View:

@model BraveryBranded.ASP.Areas.Admin.Models.News

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

    <script type="text/javascript" src="~/Scripts/tinymce/tinymce.min.js"></script>
    <script type="text/javascript">
        tinymce.init({
            selector: "textarea",
            plugins: [
            "advlist autolink link lists charmap print preview hr anchor pagebreak spellchecker",
            "searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media image nonbreaking",
            "save table contextmenu directionality emoticons template paste textcolor"
            ],
            width: 700,
            height: 250,
        });
    </script>

    @if (!String.IsNullOrEmpty(ViewBag.AlertMessage))
    {
        <text>
            <script type="text/javascript">
                alert('@Html.Raw(ViewBag.AlertMessage)');
            </script>
        </text>
        ViewBag.AlertMessage = String.Empty;
    }
}

@{
    ViewBag.Title = "Nova notícia";
}

<h2>@ViewBag.Title</h2>
<hr />
@using (Html.BeginForm("Create", "News", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>News</legend>

            @Html.HiddenFor(model => model.IdNews)
        <div class="editor-label">
            *Título:
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>
        <br />
        <div class="editor-label">
            Selecione uma imagem (imagem que representa o post na página inicial):
        </div>
        <div class="editor-field">
            <input type="file" name="fileUpload" accept="image/jpg, image/jpeg, image/png" id="file_upload" />
            @Html.ValidationMessageFor(model => model.ImagePath)
        </div>
        <br />
        <div class="editor-label">
            *Descrição (deve conter entre 100 e 5000 caracteres):
        </div>
        <div class="editor-field">
            @Html.TextAreaFor(model => model.Description, new { @style="height:180px; width:550px;", @required="required" })
            @Html.ValidationMessageFor(model => model.Description)
        </div>
        <br />
        <p>
            <button type="submit" class="btn btn-success" onclick="return confirm('Revise o nome da galeria antes de confirmar');">Adicionar</button>
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Voltar para a lista", "List", null, new { @class = "btn btn-sm btn-primary" })
</div>

Print to help with understanding:

Anotherquestionisalsowhyinthecaseofthetitle,it"checks" if it is filled before entering the controller and in the case of the description, does it enter the controller before? I checked this with a breakpoint.

    
asked by anonymous 16.07.2014 / 05:41

1 answer

5

This here:

@Html.HiddenFor(model => model.IdNews)

Make ModelState try to validate the key IdNews , which has no value in Action Create .

Remove hidden and test validation again.

    
16.07.2014 / 06:41