简体   繁体   中英

asp.net mvc, razor partial view - boolean property not showing

Here is a JQuery Datatable where I select the mode - edit, details or delete.

The 1 row shows that the boolean PublishedSwitch = true.

在此处输入图像描述


For the edit and delete modes, the boolean - PublishedSwitch (as a radio button) will NOT show as true (selected). However, it is passed in the corresponding view model with a value = true.

There is NO checked attribute.

在此处输入图像描述

Also, for the edit mode, if I click the save button, the view model 'required' data annotation kicks in stating "Publish Option required". It does not seem to recognize that it came in with a value = true. If I select the radio button, the validation passes so the setting aspect is fine.

The edit mode partial view is rendered in a Bootstrap modal whereby I send it the properties in a view model.

The delete view-only partial view is rendered in a Bootstrap modal whereby I send it the properties in a view model. (For sake of keeping it light, I will not show the delete mode code).


Note: I have a similar (almost identical) blog maintenance function with edit, details and delete partial views. For that one, I have the same radio button setup for the PublishSwitch. It works fine there for the edit, delete and details. When the view models contains a PublishSwitch value of true, the radio button is selected - shows as true in all the views. There IS a checked attribute.

Here are screen shots of the blog maintenance - edit mode.

The view model just before it is sent to the partial view.

在此处输入图像描述

在此处输入图像描述

Has the checked attribute.

在此处输入图像描述

I compared the 2 sets of code and they are the same. So I don't get why it does not show properly in this case.


For the details mode, the boolean - PublishedSwitch (as a radio button) shows just fine as selected.

At the bottom, I show the code and screens shot for the view-only details partial view. The view-only details partial view is rendered in a Bootstrap modal whereby I send it the properties in a view model.


For the edit mode:

Here is a screen shot depicting the view model just before it is sent to the partial view.

在此处输入图像描述

Here's the partial view - _EditGbngUpdate.cshtml:

@model GbngWebClient.Models.GbngUpdateDetailForMaintVM

@{
  Layout = null;
}

@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Styles.Render("~/Content/css")

<div id="modalView" class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" id="xClose" class="close" aria-hidden="true">×</button>

            <h4 class="modal-title"><strong>Edit Gbng Update</strong></h4>
        </div>

    @using (Ajax.BeginForm("EditGbngUpdate", "GbngUpdateMaint", null, new AjaxOptions { HttpMethod = "Post", OnSuccess = "UpdateGbngUpdateSuccess" }, new { @class = "form-horizontal", role = "form" }))
    {
        <div class="modal-body">
            <div class="form-horizontal">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })

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

                <div class="form-group">
                    @Html.LabelFor(model => model.GbngUpdateTitle, htmlAttributes: new { @class = "control-label col-md-2 manadatory" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.GbngUpdateTitle, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.GbngUpdateTitle, "", new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.GbngUpdateContent, htmlAttributes: new { @class = "control-label col-md-2 manadatory" })
                    <div class="col-md-10">
                             @Html.TextAreaFor(model => model.GbngUpdateContent, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.GbngUpdateContent, "", new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.PublishedSwitch, htmlAttributes: new { @class = "control-label col-md-2 manadatory" })
                    <div class="col-md-10">
                        Publish
                        @Html.RadioButtonFor(model => model.PublishedSwitch, true, htmlAttributes: new { @id = "PublishedSwitchTrue" })
                        Un-Publish
                        @Html.RadioButtonFor(model => model.PublishedSwitch, false, htmlAttributes: new { @id = "PublishedSwitchFalse" })
                    </div>
                    @Html.ValidationMessageFor(model => model.PublishedSwitch, "", new { @class = "text-danger" })
                </div>

                @if (Model.PublishedSwitch == false)
                {
                    <div>
                        <br />
                        <strong class="warningdescr">Warning: Before you publish this gbng update, be aware that you will NOT be able to unpublish it after you publish it. Also, once published, you cannot modify it or delete it.</strong>
                    </div>
                }
            </div>
        </div>

        <div class="modal-footer">
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" class="btn btn-primary" value="Save" />
                    <button type="button" id="buttonClose" class="btn btn-default">Close</button>
                </div>
            </div>
        </div>

        // To stop forgery - CSRF.
        @Html.AntiForgeryToken()
    }
</div>
</div>

<script type="text/javascript">
    $(function () {
        $('#xClose').on('click', function () {
            $('#modalView').modal('hide');
            let myurl = "/GbngUpdateMaint/Index";
            window.location.href = myurl;
        })

        $('#buttonClose').on('click', function () {
            $('#modalView').modal('hide');
            let myurl = "/GbngUpdateMaint/Index";
            window.location.href = myurl;
        })
    })

    tinymce.init({ selector: 'textarea' });
</script>

Here's it's view model - GbngUpdateDetailForMaintVM:

using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace GbngWebClient.Models
{
    public class GbngUpdateDetailForMaintVM
    {
        public int GbngUpdateId { get; set; }

        [Required(ErrorMessage = "Gbng Update Title required")]
        [MinLength(5, ErrorMessage = "Gbng Update Title Must Be At Least 5 characters")]
        [Display(Name = "Title: ")]
        public string GbngUpdateTitle { get; set; }

        [Required(ErrorMessage = "Gbng Update Content required")]
        [MinLength(10, ErrorMessage = "Gbng Update Content Must Be At Least 10 characters")]
        [AllowHtml]
        [Display(Name = "Content: ")]
        public string GbngUpdateContent { get; set; }

        [Required(ErrorMessage = "Publish Option required")]
        [Display(Name = "Publish Option: ")]
        public bool PublishedSwitch { get; set; }
   }

}

Here is a screen shot depicting the view where the PublishSwith (as a radio button) will NOT show.

在此处输入图像描述

For the details view-only mode:

In this view-only details view the boolean - PublishedSwitch (as a radio button) - shows just fine.

It's a view-only details partial view presented in a Bootstrap modal whereby I send it the properties in a view model.

Here is a screen shot depicting the view model just before it is sent to the partial view.

在此处输入图像描述

Here's the partial view - _DetailsGbngUpdate.cshtml:

@model GbngWebClient.Models.GbngUpdateDetailVM

@{
    Layout = null;
}

@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Styles.Render("~/Content/css")

<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>

            <h4 class="modal-title"><strong>Gbng Update's Details</strong></h4>
        </div>

    @using (Ajax.BeginForm(null))
    {
        <div class="modal-body">
            <div class="form-horizontal">
                 @Html.ValidationSummary(true, "", new { @class = "text-danger" })

                <div class="form-group">
                    @Html.LabelFor(model => model.GbngUpdateTitle, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-10">
                        @* Note: I used EditorFor here instead of TextAreaFor as the width was too small. *@
                        @Html.EditorFor(model => model.GbngUpdateTitle, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.GbngUpdateContent, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-10">
                        @* Multi-line text box. *@
                        @* Note: I had to set the htmlAttributes this way to get it to be disabled. *@
                        @*           If I use: new { htmlAttributes = new { @disabled = "disabled" } }, it will NOT be disabled. *@
                        @Html.TextAreaFor(model => model.GbngUpdateContent, htmlAttributes: new { @disabled = "disabled" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.PublishedSwitch, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        Publish
                        @Html.RadioButtonFor(model => model.PublishedSwitch, true, htmlAttributes: new { @disabled = "disabled" })
                        Un-Publish
                        @Html.RadioButtonFor(model => model.PublishedSwitch, false, htmlAttributes: new { @disabled = "disabled" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.PublishedDateTime, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        @Html.EditorFor(model => model.PublishedDateTime, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.AlertSentSwitch, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        @Html.EditorFor(model => model.AlertSentSwitch, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.CreatedDateTime, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        @Html.EditorFor(model => model.CreatedDateTime, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.CreatorsUserName, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        @Html.EditorFor(model => model.CreatorsUserName, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.ModifiedDateTime, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        @Html.EditorFor(model => model.ModifiedDateTime, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.ModifiersUserName, htmlAttributes: new { @class = "col-md-2" })
                    <div class="col-md-5">
                        @Html.EditorFor(model => model.ModifiersUserName, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
                    </div>
                </div>
            </div>
        </div>

        <div class="modal-footer">
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">  
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    }
</div>

Here's the view model - GbngUpdateDetailVM:

using System;
using System.ComponentModel.DataAnnotations;

namespace GbngWebClient.Models
{
    public class GbngUpdateDetailVM
    {   
        public int GbngUpdateId { get; set; }

        [Display(Name = "Title: ")]
        public string GbngUpdateTitle { get; set; }

        [Display(Name = "Content: ")]
        public string GbngUpdateContent { get; set; }

        [Display(Name = "Publish Option: ")]
        public bool PublishedSwitch { get; set; }

        [Display(Name = "Published Date: ")]
        public DateTime? PublishedDateTime { get; set; }

        [Display(Name = "Email Alert Sent: ")]
        public bool AlertSentSwitch { get; set; }

        [Display(Name = "Modified Date: ")]
        public DateTime ModifiedDateTime { get; set; }

        [Display(Name = "Modifier:")]
        public string ModifiersUserName { get; set; }

        [Display(Name = "Created Date: ")]
        public DateTime CreatedDateTime { get; set; }

        [Display(Name = "Creator: ")]
        public string CreatorsUserName { get; set; }
    }
}

Here is a screen shot depicting the view where the PublishSwith (as a radio button) is shown just fine.

在此处输入图像描述

The problem is the model binding is getting confused because I named an action parameter (in the action method that was sending the partial view) the same as my model property - publishedSwitch.

 public async Task<ActionResult> 
 EditGbngUpdate(int gbngUpdateId, bool publishedSwitch, bool 
 alertSentSwitch).

I changed the name of the action parameter - publishedSwitch. Now it works fine. Weird I know as I never considered it. A tough one to figure out, but after more research, I discovered the solution in another stackoverflow similar situation. So I give credit to AJ in Using Html.RadioButtonFor with a boolean isn't writing Checked="Checked"

Note: my blog maintenance version worked fine because in that case, I did not need to include that action parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM