views:

151

answers:

2

In my view I'm returning some results from a webservice and storing them in a session variable.

Here's the Session Storage Method:

//AreaSummary[] is a reference to the webservice reference gubbins

 public AreaSummary[] Results
        {
            get
            {
                if (this.Results != null)
                {
                    return this.Results;
                }
                else
                {
                    if (HttpContext.Current.Session["Results"] != null)
                    {
                        this.Results = 
                                   (AreaSummary[])HttpContext.Current.Session["Results"];
                                   return this.Results;
                    }
                    else
                    {
                        return null;
                    }
                }
            }

            set
            {
                this.Results= null;
                HttpContext.Current.Session["Results"] = value;
            }
        }

In the Controller I set the results to this session to save having to push the request again and again (for paging).

So I set the session to the result set:

this.mySess.SessionVarss.Results = myservice.SearchForX("stuff");

Both the 'Results' and 'SearchForX' are of AreaSummary[]

ViewData["ResultSet"] = this.mySess.SessionVars.Results;

I then pass this as ViewData in the controller without an issue and databind it to a repeater or datagrid (that i get).

My first thought was to use a foreach loop.

So in the view I was trying:

<% foreach (var item in (ViewData["ResultSet"] as List<MyMVC.webservice.AreaSummary[]>))
   { %>    
            <li class="image">
                <img src="<%=item.MainImage.ImageUrl %>" />
            </li>
<% } %>

I'm sure the mistake is glaringly obvious to some and I'm missing it through the tunnel-vision.

It compiles fine, but dies with the following error:

Object reference not set to an instance of an object.

The following works:

<% 
   placelist.DataSource = ViewData["ResultSet"];
   placelist.DataBind();
%>
<asp:Repeater ID="productlist" runat="server" Visible="true">
 <ItemTemplate>
   <li class="image">
       <img src="<%# DataBinder.Eval(Container.DataItem, "MainImage.ImageUrl")%>" />
   </li>
 </ItemTemplate>
</asp:Repeater>

But I'd prefer to use a foreach loop as some of the items returned are arrays and with the repeater I'll end up doing more.

Proper Solution

The better solution in the end was to pass the data to the view:

return View("index",SearchResults);

Then right click -> add view, index, create strongly typed view, select webservice.AreaSummary and list.

A: 

Your for loop looks ok to me although the session and viewdata are not quite the same thing.

Viewdata is stored on the session but anything stored in the session directly has to be referenced from the session in the view. In your case you store the value in Session["Results"] and then try to reference it in the view from ViewData["ResultSet"].

The below looks a bit suspect also.

public AreaSummary[] Results
    {
        get
        {
            if (this.Results != null)
            {
                return this.Results;
            }

Thats a recursive call and it looks a bit wonky. You are referencing the Property getter inside the getter, are you suppose to be referencing a field instead?

madcapnmckay
In the control I'm passing the the session back to the view... -- ViewData["ResultSet"] = this.mySess.SessionVarss.Results; -- If I use a data-repeater and databind it works fine.
Chris M
+1  A: 

I just posted this example in another question. Try something like this,

<table class="results" width="100%" border="0" cellpadding="5">
<thead class="tablehead">
  <tr> 
    <td width="55px"><b>Country</b></td>
    <td width="55px"><b>State</b></td>
    <td width="55px"><b>City</b></td>
    <td width="55px"><b>Town</b></td>
    <td width="55px"><b>Postal</b></td>
  </tr>
</thead>
<tbody>
<% 
    int count = 0;
    foreach (var item in (IEnumerable<MY_RESULTS>)ViewData["My_Results"])
    {
        if (count % 2 == 0) { Response.Write("<tr class='even'>"); } else { Response.Write("<tr class='odd'>"); }   
    %>
            <td><%= Html.Encode(item.Country)%></td>
            <td><%= Html.Encode(item.State)%></td>
            <td><%= Html.Encode(item.City)%></td>
            <td><%= Html.Encode(item.Town)%></td>
            <td><%= Html.Encode(item.Postal)%></td>
        </tr>

    <% count += 1; } %>
</tbody>
</table>
Tony Borf
You my good man were very close to the mark.foreach(var item in (IEnumerable<mymvc.webservice.AreaSummary>)ViewData["Results"])It was winging about AreaSummary not being of IEnumerable, so thats just what I needed :o) Thanks, not i dont have to use the repeater
Chris M
Glad to help <><
Tony Borf