0

I am trying to return a view that excludes rows to which the user had clicked to hide and a cookie is generated storing information of which rows the user wishes to hide.

My issue is that the cookie only contains one value, and so my select statement only excludes one row at a time. Here's what I have:

public ActionResult Hide(int id)
    {
        HttpCookie cookie = new HttpCookie("HideCookie");
        cookie.Value = id.ToString();
        cookie.Expires = DateTime.Now.AddYears(1);
        System.Web.HttpContext.Current.Response.Cookies.Add(cookie);

        int i = Convert.ToInt32(Request.Cookies.Get("HideCookie").Value);
        var quotes = from q in db.View1 where !q.Quote_ID.Equals(i) select q;

        return View(quotes.ToList());
     }

I've tried creating a string and keep appending new values to the string but it still only takes the last value clicked.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260

1 Answers1

0

I'm not sold that cookies are the best way to do this (have you considered using TempData, or at least the Session object so that you only send a single cookie to each user?) Using this approach though, it seems you could do it by using a comma-separated list for the cookie object.

public ActionResult Hide(int id)
{
    var cookie = Request.Cookies.Get("HideCookie");
    List<string> hideItems;
    if (cookie == null)
    {
        cookie = new HttpCookie("HideCookie");
        hideItems = new List<string>() { id.ToString() };
        cookie.Value = id.ToString();
        cookie.Expires = DateTime.Now.AddYears(1);
        System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
    }
    else
    {
        cookie = Request.Cookies.Get("HideCookie");
        hideItems = cookie.Value.Split(',').ToList();
        hideItems.Add(id.ToString());
        cookie.Value = string.Join(",", hideItems);
    }

    var quotes = from q in db.View1 where 
        !hideItems.Select(i=>int.Parse(i)).Contains(q.Quote_ID) select q;

    return View(quotes.ToList());
 }
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • Thanks for the reply. The assignment requires me to use cookies to hide so I've no choice in that. I had to change the split and join methods a little to get the syntax working. hideItems = cookie.Value.Split(',').ToList(); cookie.Value = string.Join(",", hideItems.ToArray()); I can't get the view to return though since hideItems is a string and Quote_ID is an int and can't be compared. I get "LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression." when I try to use the ToString method on it – user1354780 Apr 24 '12 at 23:42
  • @user1354780 ah right ... please see the update. You can convert the list to a list before doing the compare. – McGarnagle Apr 24 '12 at 23:44
  • Looks like I had a few more typos in there (in string.join and string.split). Should be fixed now... looks like I need more coffee :-( – McGarnagle Apr 24 '12 at 23:47
  • I still have an error "LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression." It seems the where clause you've given makes the var quotes no longer a select statement. When I debug it, it has the value of {System.Data.Entity.Infrastructure.DbQuery} – user1354780 Apr 26 '12 at 13:39
  • I've made a new List that contains ints and used a foreach loop to send the values from hideItems to my list of ints. I am able to use the code: var quotes = from q in db.View1 where !hide.Contains(q.Quote_ID) select q; The issue now is it only hides one row at a time, which is the last quote_ID clicked. The one hidden previously reappears. Edit: I got it to work, it seems I needed to add the cookie again at the end in the else statement. Thanks for all your help. Works like a charm now. – user1354780 Apr 26 '12 at 16:10
  • @user1354780 Ah right, makes sense you'd have to re-add the cookie to the response object. I forgot about that. – McGarnagle Apr 26 '12 at 17:54