Solved

MVC 5 Partial View using ViewData or TempData Not Working?

Posted on 2014-10-09
10
1,420 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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 500 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
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…
I designed this idea while studying technology in the classroom.  This is a semester long project.  Students are asked to take photographs on a specific topic which they find meaningful, it can be a place or situation such as travel or homelessness.…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

914 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now