简体   繁体   中英

Model values not carrying into partial view from main view- C# MVC

I've been stumped for days.

I have an index page that contains a renderpartial view. A viewmodel is passed to the index page from its controller, then passed from inside the index.cshtml to the renderpartial view as an extension. The renderpartial view is automatically updated every 10 seconds (via jquery function to the controller from the index page) to update its content, which works fine. The index page contains several checkboxfor's that filter out the contents of the renderpartial view. The problem arises when the initial renderpartial view is called when the time period has elapsed, the controller for the renderpartial view does not have the correct model data the controller for the index had prior. Boolean values in the model which were set to true while in the index controller now are false when we get to the renderpartial view. Lets begin...

My Index View:

@model SelfServe_Test2.Models.NGTransCertViewModel

...        

    <div class="Services_StatusTable" id="refreshme">        
    @{            
        Html.RenderPartial("_Data", Model);
    }            
    </div>

...

@Html.CheckBoxFor(m => m.NGTransServicesModel.filter_NJDVSVR24, new { onclick = "test(id)" }) @Html.Label("NJDVSVR24", new { })

...

<script src="~/Scripts/jquery-1.12.4.js"></script>
<script type="text/javascript">
    $(function () {
        setInterval(function () { $('#refreshme').load('/NGTransCertServices/Data'); }, 10000); // every 10 seconds

    function test(filter) {
        alert(filter);
        var serviceChecked = document.getElementById(filter).checked;
        $.ajax({
            type: "POST",
            url: "/NGTransCertServices/ToggleVisibleService",
            data: { 'filterOnService': filter, 'serviceChecked': serviceChecked, 'model': @Model },
            //success: function (result) {
            //    if (result === "True")
            //        alert("yup");
            //    else
            //        alert("nope");
            //}
        });
    }

</script>

The PartialView _Data.cshtml:

@model SelfServe_Test2.Models.NGTransCertViewModel

...

<table>
foreach (var item in Model.NGTransServicesList)
{

    if (Model.NGTransServicesModel.filter_EBT == true)
    {
        if (item.Description.Contains("EBT"))
        {

        }
    }
}
</table>

My ViewModel:

namespace SelfServe_Test2.Models
{
public class NGTransCertViewModel
{
    public NGTransCertViewModel()
    {
        NGTransServicesModel = new NGTransCertServicesModel();
        NGTransServicesList = new List<NGTransCertServicesList>();
        NGTransServices = new NGTransCertServices();
    }
    public NGTransCertServicesModel NGTransServicesModel { get; set; }
    public List<NGTransCertServicesList> NGTransServicesList { get; set; }
    public NGTransCertServices NGTransServices { get; set; }
}
}

The Controller:

 public class NGTransCertServicesController : Controller
{
    NGTransCertViewModel NGT_VM = new NGTransCertViewModel();
    NGTransCertServicesModel certServicesModel = new NGTransCertServicesModel();

    public ActionResult Index()
    {            
        NGTransCertServices certServices = new NGTransCertServices();                        
        NGT_VM.NGTransServicesModel = certServices.InitServiceTypeCheckBoxes(certServicesModel);   // sets all checkboxes to true initially.
        return View(NGT_VM);
    }


    [OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.Client, Duration = 10)]    // in seconds
    public ActionResult Data()
    {
        NGTransCertDBHandle certDBHandle = new NGTransCertDBHandle();
        List<NGTransCertServicesList> List_certServices = certDBHandle.GetService();
        return PartialView("_Data", NGT_VM);
    }
}

Finally, the model where the values are lost:

 public class NGTransCertServicesModel
{
    ...
    public bool filter_NJDVSVR24 { get; set; }
    ...
}

Now then, when the Index.cshtml page is called, i run the InitServiceTypeCheckBoxes method that sets the checkbox values to true, pass the viewmodel to the index page and pass that same model to the renderpartial. All is happy until the 10s timeout is reached and _Data.cshtml is rendered. The checkbox values are now all false.

Let me add a visual element. Below is the model when returning from the controller to the index view with the Boolean set to true as desired. (stepping through) 在此处输入图片说明

Below is the model when the index view 在此处输入图片说明

Again, in the _Data.cshtml partial view 在此处输入图片说明

Now with a breakpoint in the Data action in the controller, that same bool value is now false 在此处输入图片说明

The bool does not have the true value even before the first line of code in the Data action.

NGTransCertDBHandle certDBHandle = new NGTransCertDBHandle();

I think the issue is that you're not populating your view model correctly in the Data method of your controller.

In both methods you're sending the NGT_VM property to the view, but you only populate some of the data in the Index method - this data will not be persisted or created by default when you call the Data method.

Each time a request hits a controller method, that controller is created afresh, and only the constructor and requested method are called. In the case of a request to Data the controller is created, the NGT_VM property is set back to the default NGTransCertViewModel object, with a default NGTransCertServicesModel object (the boolean property filter_NJDVSVR24 will default to false ). You then create and ignore a variable List_certServices , but at no point have you updated the NGTransServicesModel property on the view model to match the values you had from the Index method.

You should probably assign the NGTransServicesList variable to the NGT_VM.NGTransServicesList after you populate it:

[OutputCache(NoStore = true, 
             Location = System.Web.UI.OutputCacheLocation.Client,
             Duration = 10)]
public ActionResult Data()
{
    NGTransCertDBHandle certDBHandle = new NGTransCertDBHandle();
    List<NGTransCertServicesList> List_certServices = certDBHandle.GetService();
    NGT_VM.NGTransServicesList = List_certServices;
    return PartialView("_Data", NGT_VM);
}

You could either call same methods to update the NGTransServicesModel as required in the Data method, but I'm not sure that's really the behaviour you're after?

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