0

I'm working with an MVC view that displays some text with HTML markup. I have the field defined in my view model like this:

public class RequestReviewViewModel
{
    [Display(Name = "Email Body")]
    [AllowHtml]
    [DataType(DataType.MultilineText)]
    public string LetterTemplateBody { get; set; }
}

When the user selects a new option in a dropdown list I am catching the postback and updating the field with new data to display in a TextArea. However the TextArea doesn't change.

I have this code in my controller:

var letterTemplList = 
    db.EmailBodyTemplate.Where(x => x.EmailTemplateTypeId == (int)EmailTemplateTypes.requestreview).ToList();
ViewBag.LetterTemplates = 
    new SelectList(letterTemplList, "EmailTemplateId", "EmailTemplateName");
var letterTemplate = 
    letterTemplList.Find(x => x.EmailTemplateId == thisModel.LetterTemplateId);
thisModel.LetterTemplateBody = 
    letterTemplate == null ? letterTemplList.First().Body : letterTemplate.Body;

// in this case, mode == "letterTemplate"
if (mode == "reviewRole" || mode == "letterTemplate" || !ModelState.IsValid)
{
    if (model.InitialRoleId != model.SelectedRoleId)
        model.SelectedProjectReviewers = GetReviewerProfiles(model.ProjectId, model.SelectedRoleId);

    return View(model);
}

This is where the field is displayed:

<div class="row">
    @Html.LabelFor(model => model.LetterTemplateBody, new { @class = "control-label" })
    @Html.TextAreaFor(model => model.LetterTemplateBody, 
        new { @class = "form-control", @style = "max-width:100%;height:400px;font-size:11px;" })
</div>
<p>@Model.LetterTemplateBody</p>

With the debugger, I can see the model.LetterTemplateBody has the new results. However, when I look at the page (in chrome) the value/data hasn't changed in the TextArea, but the <p> has.

What could be causing what the textarea to not get updated? Other callbacks update the page with the same controller actions.

Here is how it's rendered in the browser:

<textarea 
    class="form-control" 
    cols="20" 
    id="LetterTemplateBody" 
    name="LetterTemplateBody" 
    rows="2" 
    style="max-width:100%;height:400px;font-size:11px;">
Text from initial load
</textarea>
M Kenyon II
  • 4,136
  • 4
  • 46
  • 94
  • Your code looks correct, does it output anything when you put

    @Model.LetterTemplateBody

    in the cshtml?
    – Danny Nov 12 '15 at 16:41
  • Good thought, it changes correctly. It is something with the TextAreaFor. – M Kenyon II Nov 12 '15 at 16:50
  • 1
    Most likely there's something in `ModelState` that's overriding the value. `ModelState` is composed from `Request`, `ViewData`, `ViewBag`, and finally `Model`, but only as a last resort. For example, if a value was posted for the textarea at some point, it would be in `Request` and that would override anything you set explicitly on `Model`. – Chris Pratt Nov 12 '15 at 16:55
  • Chris, how could I ensure the Model data is what is used? Can I clear the Request LetterTemplateBody value? – M Kenyon II Nov 12 '15 at 16:56
  • 1
    No, Request is readonly. I'm not sure what you're actually doing here, but these types of issues are normally resolved by following PRG (post-redirect-get). After you post, you only return the view if there's an error. If there's error you *want* the posted value shown, so that the user can correct any problems. If, however, it's "successful", then you redirect, even if it's back to the same URL. That way, all the cruft from the POST is cleared away. – Chris Pratt Nov 12 '15 at 17:13
  • This would be on a DropDownList change. – M Kenyon II Nov 12 '15 at 17:16
  • You have not shown your full controller code but best guess is that your posting and returning the view, in which case the HtmlHelper will use the values added to `ModelState`, not the models property values that you have updated (refer [this answer](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) for an explanation of the behavior, but as Chris has noted, you should be following the PRG pattern. –  Nov 12 '15 at 22:58
  • I've added more of my controller code. Are you saying that instead of `return View(model)` I should do something like `RedirectToAction("_requestReview",model)`? Can one of you send me a link to learn more about PRG? – M Kenyon II Nov 13 '15 at 13:39

0 Answers0