Question

In the last three days I've struggled trying to find a way to accomplish what I though was supposed to be a simple thing. Doing this on my own or searching for a solution in the web, didn't help. Maybe because I'm not even sure what to look for, when I do my researches. I'll try to explain as much as I can here: maybe someone will be able to help me.

I won't say how I'm doing it, because I've tried to do it in many ways and none of them worked for different reasons: I prefer to see a fresh advice from you.

In most of the pages of web application, I have two links (but they could be more) like that:

  • Option A
  • Option B

This is partial view, retured by a controller action.

User can select or both (all) values, but they can't never select none of them: meaning that at least one must be always selected.

These links must che accessible in almost all pages and they are not supposed to redirect to a different page, but only to store this information somewhere, to be reused when action needs to filter returned contents: a place always accessible, regarding the current controller, action or user (including non authenticated users) (session? cookie?). This information is used to filter displayed contents in the whole web application.

So, the problem is not how to create the business logi of that, but how (and where) to store this information:

  • without messing with the querystring (means: keeps the querystring as empty/clean as possible)
  • without redirecting to other pages (user must get the current page, just with different contents)
  • allow this information to persists between all views, until user click again to change the option(s)

My aim is to have this information stored in a model that will contains all options and their selection status (on/off), so the appropriates PartialView will know how to display them. Also, I could send this model to the "thing" that will handle option changes.

Thanks.

UPDATE

Following Paul's advice, I've took the Session way:

    private List<OptionSelectionModel> _userOptionPreferences;
    protected List<OptionSelectionModel> UserOptionPreferences
    {
        get
        {
            if (Session["UserOptionPreferences"] == null)
            {
                _userOptionPreferences= Lib.Options.GetOptionSelectionModelList();
            }
            else
            {
                _userOptionPreferences= Session["UserOptionPreferences"].ToString().Deserialize<List<OptionSelectionModel>>();
            }

            if (_userOptionPreferences.Where(g => g.Selected).Count() == 0)
            {
                foreach (var userOptionPreferencesin _userOptionPreferences)
                {
                    userOptionPreferences.Selected = true;
                }
            }

            UserOptionPreferences= _userOptionPreferences;
            return _userOptionPreferences;
        }
        private set
        {
            _userOptionPreferences= value;
            Session["UserOptionPreferences"] = _userOptionPreferences.SerializeObject();
        }
    }

Following this, I've overridden (not sure is the right conjugation of "to override" :) OnActionExecuting():

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        GetOptionSelections();

        base.OnActionExecuting(filterContext);
    }

GetOptionSelections()...

    private void GetOptionSelections()
    {
        if (String.IsNullOrEmpty(Request["optionCode"])) return;

        var newOptionCode = Request["optionCode "];
        foreach (var userOptionPreferencesin UserOptionPreferences)
        {
            if (userOptionPreferences.OptionCode == newOptionCode )
                userOptionPreferences.Selected = !userOptionPreferences.Selected;
        }
    }

This code I think can be better, but right now I just want to make it work and it doesn't.

Maybe there are also other issues there (quite sure, actually), but I believe the main issue is that OnActionExecuting is called by each action in a controller that inherit from BaseController, therefore it keeps toggling userOptionPreferences.Selected on/off, but I don't know how to make GetOptionSelections() being called only once in each View: something like the old Page_Load, but for MVC.

Last update AKA solution Ok, using the session way, I've managed to store this information.

The other issue wasn't really on topic with this question and I've managed to solve it creating a new action that take cares of handling the option's change, then redirects to the caller URL (using the usual returnUrl parameter, but as action parameter). This way, the option change is done only once per call.

The only thing I don't really like is that I can't simply work with the UserOptionPreferences property, as it doesn't change the session value, but only the value in memory, so I have to set the property with the new object's status each time: not a big deal, but not nice either.

Was it helpful?

Solution

This is a place to use session.

The session will keep your setting between requests while keeping it out of the url querystring. It seems that you have probably tried this already, but try it again and if you have problems ask again. I think it will be the best way for you to solve this problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top