Search code examples
asp.net-coremodel-view-controller

View not binding after OnChange click


enter image description hereI have a simple view that displays an email template. I use a droplist to select the template to work with. Initially, when I select the first one in the list, it binds fine. I have an OnClick post when you change the drop list that seems to work, it hits my breakpoint. I see which template has been selected, retrieve it, and send to view. It doesn't change the values that were originally displayed on the view (screeshot).

I have similar case in more than one place in my app, so obviously there is something here I don't understand.

Why does it not display the updated model values when in return View(t). I would expect the screenshot to show values from Template2.

I have attached the Model, View, and Controller code below. The screenshot is taken after the droplist is changed o Template2.

``namespace WebApplication1.Models
{
    public enum TemplateList
    {
        Template1,
        Template2,
        Template3
    }
    public class EmailTemplate
    {
        public TemplateList TemplateId { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }

        public EmailTemplate() { }


        public static List<EmailTemplate> GetTemplates()
        {
            List<EmailTemplate> templates = new List<EmailTemplate>();
                templates.Add(
                new EmailTemplate
                {
                    TemplateId = TemplateList.Template1,
                    Body = "This is template #1",
                    Subject = "Template 1"
                });
                templates.Add(
                new EmailTemplate
                {
                    TemplateId = TemplateList.Template2,
                    Body = "This is template #2",
                    Subject = "Template 2"
                });
                templates.Add(
                new EmailTemplate
                {
                    TemplateId = TemplateList.Template3,
                    Body = "This is template #3",
                    Subject = "Template 3"
                });
            return templates;
        }
    }
}

---------
@model EmailTemplate
@{
    ViewData["Title"] = "Email Edit";
}
<div class="container">
    <h5 class="text-centered">Edit Email Template</h5>
    @using (Html.BeginForm("Email", "Home", FormMethod.Post))
    {
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="row">
            <label class="control-label col-sm-1">Template</label>
            @Html.DropDownListFor(m => m.TemplateId,
        new SelectList(Enum.GetNames(typeof(TemplateList))), "", new { @class = "form-control col-sm-2", @onchange = "this.form.submit();"})
            <span asp-validation-for="TemplateId" class="text-danger"></span>
        </div>
        <div class="row">
            <label class="control-label col-sm-1">Subject</label>
            @Html.TextBoxFor(m => m.Subject, new { @class = "form-control col-sm-10"})
            <span asp-validation-for="Subject" class="text-danger"></span>
        </div>
        <div class="row">
            <label class="control-label col-sm-1">Body</label>
            @Html.TextAreaFor(m => m.Body, 20, 70, new { @class = "form-control col-sm-10"})
            <span asp-validation-for="Body" class="text-danger"></span>
        </div>

        <div class="container, text-center">
            <input type="submit" asp-action="Update" value="Update" class="btn btn-primary" />
            <input type="submit" asp-action="Index" value="Cancel" class="btn btn" />
        </div>
    }
</div>
---------------
        public IActionResult Email()
        {
            List<EmailTemplate> templates = EmailTemplate.GetTemplates();
            EmailTemplate t = templates.ElementAt(0);
            return View(t);
        }

        [HttpPost]
        public IActionResult Email(EmailTemplate template)
        {
            List<EmailTemplate> templates = EmailTemplate.GetTemplates();
            EmailTemplate t = templates.Find(m => m.TemplateId  == template.TemplateId);
            return View(t);
        }

`


Solution

  • Default Tag helper displays ModelState's value not Model. Just add ModelState.Clear() before you return View:

    [HttpPost]
    public IActionResult Email(EmailTemplate template)
    {
        List<EmailTemplate> templates = EmailTemplate.GetTemplates();
        EmailTemplate t = templates.Find(m => m.TemplateId == template.TemplateId);
        ModelState.Clear();  //add this...
        return View(t);
    }