1

I am new to MVC and facing one issue. I have a xml file and i am retrieving its value using Linq to xml and assigning it to ViewData. Controller.cs

           var res=from x in doc.Descendants("person")
                  select new 
                  {
                    Fname=x.Element("fname").Value,
                    Lname=x.Element("lname").Value

                  };
                   ViewData["Persons"]=res;

in View I am trying

         <% foreach (var item in ViewData["Persons"])   
                 { %>  


                   <li> <%= item.Fname %> </li>  


                 <% } %>  

but foreach (var item in ViewData["Persons"] is giving type casting error..what should be the exact type csting so that i can retrive values in the format item.Fname.

Thanks.

4 Answers 4

9

Using ViewData, although possible, is not the most elegant way to pass information from controller to view. Using specific view model instead makes code easier and cleaner, and resolves casting issues.

Try defining model first:

public class ViewModelElement
{
    public string Fname { get; set; }
    public string LName { get; set; }
}


public class ViewModel
{
    public List<ViewModelElement> Elements { get; set; };
}

Then use your model in action:

public ActionResult ActionName()
{
  //get doc somehow
  var model = new ViewModel();

  //When querying by linq to xml, you can create ViewModelElement instead of anonymous class
  model.Elements = (from x in doc.Descendants("person")
      select new ViewModelElement
      {
        Fname=x.Element("fname").Value,
        Lname=x.Element("lname").Value
      }).ToList();

  return View(model);
}

Then use your model in view:

<% foreach (var item in model.Elements) { %>  
   <li> <%= item.Fname %> </li>  
<% } %> 

View has to inherit from System.Web.Mvc.ViewPage<ViewModel>.

Sign up to request clarification or add additional context in comments.

2 Comments

select new ViewModelElement is giving casting problem..it says cant convert from type Generic.Ienumerable to Generic.List
@Wondering: You can add .ToList() when setting Elements. This is your problem? I corrected my solution.
1

The problem with your existing code is that you're projecting your data into an anonymous type with your Linq query, so there is no named type to cast to.

Assuming you had a named type (Person) to cast to (and you still wanted to use ViewData), your solution would be:

<% foreach (var item in (IEnumerable<Person>)ViewData["Persons"])

But inheriting your page from a strongly-typed ViewModel object is a better solution.

Comments

0

The default type in ViewData collection for a non-strongly typed view is object.

Your view is throwing an exception because it cannot automatically cast from object back to IEnumerable which LINQ queries return.

Change your loop to this and it should work fine:

  <% foreach (var item in (IEnumerable)ViewData["Persons"])   
                 { %>  


                   <li> <%= item.Fname %> </li>  


                 <% } %> 

By far the best advice is to strongly type your views so that you can do what LukLed suggested

1 Comment

I am unable to retrive item.Fname..actually Fname is not coming in intellisense itself.
0

Personally I really can only think of one (but I am sure there a few more instances) reason to use view data is so that I can fetch some data on client without making callback to server. When you make an HTTP request you typically make a query against the database and render the results.

Very rarely do you need to hide/store some other data that you may or may not need based on the rendering to the point that you do not wish to callback the database for more data. Besides, things may have changed on the database making the stored data useless. Session state or unique user data would likely be stored in some other method but tbat might be a reason to use it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.