?
Solved

MVC 5 Partial View using ViewData or TempData Not Working?

Posted on 2014-10-09
10
Medium Priority
?
1,664 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Independent Software Vendors: 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

One of the pain points with developing AJAX, JavaScript, JQuery, and other client-side behaviors is that JavaScript doesn’t allow for cross domain request for pulling content. For example, JavaScript code on www.johnchapman.name could not pull conte…
Sometimes in DotNetNuke module development you want to swap controls within the same module definition.  In doing this DNN (somewhat annoyingly) swaps the Skin and Container definitions to the default admin selections.  To get around this you need t…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses
Course of the Month7 days, 23 hours left to enroll

765 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