Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

MVC 5 Partial View using ViewData or TempData Not Working?

Posted on 2014-10-09
10
Medium Priority
?
1,785 Views
Last Modified: 2014-10-14
I'm calling an ActionResult which then returns a Partial View with a foreach ViewData / TempData containing a list of strings. So far the app runs without any errors and I don't see any messages showing in the Partial View either.

The goal is to have the Partial View show a building list of completed tasks like so:
   * New Cars Import Successful
   * Used Cars Import Successful

Here's what I have so far.
[View]
   <div>
       @using (Ajax.BeginForm("Import", "Excel", new AjaxOptions ....
        <input id="submit" type="submit" .... 
   </div>
   
   <div>    
        @{ Html.RenderPartial("_ImportStatus"); }    
  </div>

[Partial View]
   <h4>Excel Import Status:</h4>

<ul>
    @{ List<string> list = TempData["list"] as List<string>;
           if (list != null && list.Count > 0)
           {
               foreach (var item in list)
              {
                  <li>item</li>
              }
           }
       }
</ul>
  
[Controller]
   public async Task<ActionResult> Import (viewModel model)
   {
         foreach (var tab in model.Sheets) //Excel
         {
              if (tab.Name.Contains("NewCars"))
              {
                    await GetNewCars(model);
              }

              if (tab.Name.Contains("UsedCars"))
              {
                    await GetUsedCars(model);
              }
         }
    }

     public async Task<ActionResult> GetNewCars(viewModel model)
     {
         // Entity import code

            List<string> list = new List<string>();
            list.Add("New Cars Import Successful!");

            TempData["list"] = (List<string>)list;
            
            return PartialView("_ImportStatus");
        }

       public async Task<ActionResult> GetUsedCars(viewModel model)
       {
         // Entity import code

            List<string> list = new List<string>();
            list.Add("Used Cars Import Successful!");

            TempData["list"] = (List<string>)list;
            
            return PartialView("_ImportStatus");
        }

Open in new window

0
Comment
Question by:WorknHardr
  • 5
  • 5
10 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40372916
I prefer to use a view model, rather than ViewData/TempData, so that I can get Intellisense.  You would need to pass in the view model as a @model argument, and then you should be able to access the properties in the partial view.
0
 

Author Comment

by:WorknHardr
ID: 40373257
Understood, I like using Models. To be clear, both GetNewCars and GetUsedCars will be called and each adds its message to the same persisted List<String>. I don't think the same Partial View will show the entire list of messages. I'm unsure how to make a static List<sting> which will keep each message added to it.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40373707
"I don't think the same Partial View will show the entire list of messages. "
This is a case of not understanding the entire problem.  Can you show me how the data hierarchy?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:WorknHardr
ID: 40374155
Okay, using a Model now. I'm working with the Status string now just for testing.

   public class viewModel
    {        
          public List<string> StatusList { get; set; }
          public string Status { get; set; }
    }

I've also setup a simple Partial View to see if it will display a simple Status string.
My goal is to add several messages to the StatusList

[Controller]
  public async Task<ActionResult> GetUsedCars(viewModel model)
       {
          try
          {
              // Entity import code
          }
          catch{}

           model.Status = "Used Cars Import Successful!";
            
            return PartialView("_ImportStatus", model); //debugger shows the correct values for model.Status
        }

[View]
  [View]
   <div>
       @using (Ajax.BeginForm("Import", "Excel", new AjaxOptions ....
        <input id="submit" type="submit" .... 
   </div>
   
   <div>    
        @{ Html.RenderPartial("_ImportStatus", Model); }    
  </div>

[Partial View]
   @model viewModel

<h4>Import Status:</h4> //this shows in main view

@Html.LabelFor(m => m.Status); //this never shows anything

Open in new window

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40374178
How are you generating the viewModel class?
0
 

Author Comment

by:WorknHardr
ID: 40374400
I don't what you mean by 'generating'.

I think the big problem is using the Ajax.BeginForm which calls the 'Import' Action. It only has one return when the entire Action is run. It returns a result to it's TargetID. So GetNewCars and GetUsedCars methods must return to the Import Action on code completion. Then the TargetID gets the final List<string>. This is not my goal...

[View]
   @using (Ajax.BeginForm("Import", "Excel", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "result"}))
    {}
    <div id="result"></div>


[Controller]
   public async Task<ActionResult> Import (viewModel model)
   {
         model.StatusList = new List<string>(); // using the List<string.> again

         foreach (var tab in model.Sheets) //Excel
         {
              if (tab.Name.Contains("NewCars"))
              {
                    string message = await GetNewCars(model);
                    model.StatusList.Add(message);
              }

              if (tab.Name.Contains("UsedCars"))
              {
                    string message = await GetUsedCars(model);
                    model.StatusList.Add(message);
              }
         }
       return Content(model.StatusList));
    }

     public async Task<String> GetNewCars(viewModel model)
     {
          // Entity import code
           
            return "New Cars Import Successful"
        }

       public async Task<String> GetUsedCars(viewModel model)
       {
          // Entity import code

           return "Used Cars Import Successful"
        }
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 40377051
Maybe a better word would be "constructing"...I still don't see where the viewModel instance is constructed.
0
 

Author Comment

by:WorknHardr
ID: 40377397
The first View has the button click is build like so.

[Index View]
  @model viewModel
  @{
         ViewBag.Title = "";
     }

     <div>
       @using (Ajax.BeginForm("Import", "Excel", new AjaxOptions ....
        <input id="submit" type="submit" .... 
   </div>
   
   <div>    
        @{ Html.RenderPartial("_ImportStatus", Model); }     
  </div>

[index Action]
   viewModel model = new viewModel
   {
        Sheets = list
   };

[Models]
   public class viewModel
    {
        public string Name { get; set; }
        public List<Sheetss> Sheets { get; set; }
        public List<string> StatusList { get; set; }
        public string Status { get; set; }
    }

    public class Sheetss
    {
        public string Name { get; set; }
        public string Option { get; set; }        
    }

Open in new window

0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 2000 total points
ID: 40380036
1) You create a view model with Sheets property set to a list.

2) You pass the view model to the partial view:

@{ Html.RenderPartial("_ImportStatus", Model);

3) You use the model in the partial view:

   @model viewModel

<h4>Import Status:</h4> //this shows in main view

@Html.LabelFor(m => m.Status); //this never shows anything

4) Put a breakpoint on this line, and check the value in Immediate Window:

@Html.LabelFor(m => m.Status); //this never shows anything

5) If it doesn't have any value, then work your way back through the call hierarchy, and check each point with breakpoints and checking values.
0
 

Author Closing Comment

by:WorknHardr
ID: 40380748
Okay, I'll take it from here, thx
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A quick way to get a menu to work on our website, is using the Menu control and assign it to a web.sitemap using SiteMapDataSource. Example of web.sitemap file: (CODE) Sample code to add to the page menu: (CODE) Running the application, we wi…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
The Relationships Diagram is a good way to get an overall view of what a database is keeping track of. It is also where relationships are defined. A relationship specifies how two tables connect to each other. As you build tables in Microsoft Ac…
Suggested Courses

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question