I have a need to share information from Web Parts on one page, with Web Parts on a second page. SharePoint does not have a default Session State, and let's say for arguments sake I cannot enable Session.
If there is a LOT of information, more than can be sent via Query String, is there another option?
Depending on the nature of the data that needs to be passed along, there are different ways to go about it. My first idea would probably be to save it in cookies on the active user. Another alternative is to save data to the property bag of the SPUser-object of the current user.
Really feels like a scenario to user Session-state though.. :)
Related
I'm working on a project which I need to build a list of menus according with the profile of the logged user. But, currently I have to build this list each time the page is loaded and this is not too good for my project.
What I want to do is get this list only when the user logs in and use it each time that I need it. My idea is store this list in the Session when the user logs in. But I know the session isn't a good practice.
I've tried to use the session, cookie and OutputCache in ActionResult but only the session works.
Is there a way to store my list in a "global variable", or something like that, and use it always I need it?
I can suggest two options for you problem.
Use Session object for each user.
or
Use Caching mechanism - If you have implemented some caching mechanism in you application, you can create one object per one user storing the navigation menu(Something like Redis, AppFabric or .NET caching).
Object related to the menu should be create only one time for the user(You can create it during the login).
I would create a database storing the built list when profiles are created/changed (could be something as simple as a JSON string?) referenced by the user id.
Simply then a case of selecting this with a single user id value - a simple data type can get a complex datatype.
Thanks for all help.
To solve my issue, I had to use the Session. Why? Because each user has his own '(SidebarViewModel)Session["sidebar"]' which contains all specific menus, name, ids and avatar.
I've tried to use the "OutputCache" (My own attribute class), but as my menu is a ChildAction I couldn't clear my cache on logoff and it's not so good to the user who can change his own avatar when he wants to. I also tried to use the Application but it was almost the same case of the Sessions.
PS: I don't like the Sessions, but I think it's the best way for now.
I'm making a simple asp.net app that displays data which can be filtered based on a few different parameters. As such, the different filters that are currently selected need to be saved somewhere. I'm fairly new to .NET, and am wondering the best way to save this information. I noticed a coworker used Request.QueryString in conjunction with the Sessions dictionary. Something like this on page load:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["Category"] != null &&
Request.QueryString["Value"] != null)
{
string Category = Request.QueryString["Category"];
string CategoryValue = Request.QueryString["Value"];
// selectedFacets is the server side dictionary
selectedFacets.Add(Category, CategoryValue);
}
}
The QueryString here is changed when the user presses a button on the webpage, updating the URL.
My question is why even bother with the QueryString at all when all we're using it for is saving a value server side anyway? Wouldn't just making the button an asp controller be easier, something like:
protected void exampleCatexampleVal_Button_onClick(object sender, EventArgs e)
{
selectedFacets.Add(exampleCat, exampleVal);
}
Similar business goes on the with the Sessions dictionary: it's just used to save a bunch of values to variables on the server, so why use it in the first place? I'm sure there's a good reason, but right now they just seems overly complicated for what they do. Thank you!
Based on your code examples, I understand that you're talking about ASP.NET WebForms.
Your use case is not complete, but I'll show here some alternatives to achieve your goal. If you give further information, I'll gladly update my answer.
Before we get to it, let me just put things clear: HTTP is stateless. Understanding this basic rule is very important. It means that your server will receive a request, send it to your app (and the .NET process), get the resulting page (and assets) and send it back to the client (mostly, a browser). End of story.
(Almost) Everything that you've created to respond to the request will be lost. And that's why we have options on where to store objects/values across requests.
Server-side Session
This is one of the easiest options. You simply call this.Session.Add("key", object) and it's done. Let's dig into it:
It will use server resources. That is, the most you use the session, the most memory (and other resources, as needed) your app will consume.
It will be harder to scale, because data will be on your server memory. Vertical scale may be an option, according to your hardware, but horizontal scale will be limited. You can use a session-server or store session on a SQL Server database, but it won't be so efficient anymore.
It's attached to your client session. It will be lost if the user opens another browser or sends a link to his friend.
It's relatively safe. I say relatively because of the options below. At least it's server side.
GET arguments (AKA QueryString)
That's another option, and you know it already. You can send data back and forth using the querystring (?that=stuff&on=the&URL=youKnow).
It's limited to 2000 characters and that must be serializable. That's why you probably won't put a DataGrid there.
The user may change it. Be aware! Always sanitize data from the QueryString.
User is free to bookmark the link or send it to a friend and stuff will be the same. That's nice, mind you.
ViewState
You may have heard about it, it's the engine that makes WebForms so lovely (and so hateful). By default, each controller on your page will have its state serialized to the viewstate, which is a huge hidden field with encrypted data on your page. Go on, click "View source" and look for it. Don't scream, please. You may add arbitrary data to the ViewState just like the Session.
It's on the client side. Don't trust it.
It will be send back and forth on each request, so it will consume extra bandwidth.
It will take time to be deserialized/serialized on each request/response.
Data must be serializable (you know what I mean).
So, by now I hope that you have enough information to make your own decision.
If I missed anything, please let me know.
Have a look at this MSDN Article first. I read through it, and it may answer your question for you.
http://msdn.microsoft.com/en-us/magazine/cc300437.aspx
What you're missing, is how the asp.net page lifecycle works:
http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
The thing is, that 'server variable' won't persist between postbacks (AFAIK). It's only useful inside that page, right then. As soon as the page is disposed at the end of the cycle, that dictionary is gone. So you have to store it somewhere if you want to use it later. The article I referenced shows you all the places that you can store information to persist it and where you store it depends on how long you need it to persist, and how many users should have access to it.
Now, certainly, if you DON'T want to persist that dictionary, then sure, just store it the page variable. That's just fine. There's no reason to persist data that you never need again.
It's always good to keep in mind that there is a slight performance hit when storing and retrieving session state from database or from separate process service (StateServer). If session state is stored in-memory, you cannot scale your application to a web farm and this wastes valueable memory in the web server.
On the other hand, using query string values won't waste your memory and resources, it is fast and you don't have to think about managing session state. It gives SEO benefit and allows bookmarks/favorites.
However, you can store only limited amount of data using query string (WWW FAQs: What is the maximum length of a URL). It can also pose a security risk, if sensitive data is exposed or a malicious user tries to find a bug in your code that mishandles URL values. SQL injection attack is one scenario. What you can do is encrypt sensitive values.
Overall there are many aspects to consider here.
One of the benefits of using query string values is if you need bookmarks/favorites stored in your application that would allow a user to directly navigate to a page and have certain values be passed into the page without the assistance of an in-memory cache. Take the following for example:
I have a product page that displays a grid view of products that can be filtered by a category name. If I use the categoryId value in the query string, then I can make a bookmark to this page and then later click on the bookmark and the page will work as I left it earlier. Depending upon in-memory cache, that may or may not be there, would not guarantee that my bookmark would work every time.
I'm designing a web application that has to pass sensitive information (like the user's account number) from page to page until the user is done (the application is like a wizard), for logging purposes. What is the best way of storing this data so that each page in the process can get access to the data? Should I be storing it in the session? In the database, then delete it at the end? Some method I haven't thought of yet?
I personally try to avoid using the session where possible. Here are the options that I know of when dealing with wizard type scenarios:
Option 1
Use JQuery as discussed in Nadeem Afana's blog. The pages are displayed to the user one by one but the information is not submitted until the final page.
Option 2
Is the information on every page sensitive? Could it be structured so that the sensitive information is just asked for on the final page? If so you could serialize data across the pages as discussed in Darin Dimitrovs answer and just not provide a back button on the final page. Alternatively, the data that is serialized can be encrytped with ease using the same MVC Futures serialization software although i'm not sure how sensitive your information is and whether you would want to rely on this. The answer also mentions alternatives such as Stepy but I have no experience with this.
Option 3
If the information is sensitive you could write/read the information to a database between requests.
Option 4
Finally, if you can't use any of the above then I would use the Session or TempData (which is a wrapper around the session) but beware that with TempData, if the user refreshes the page then the information will be lost.
Session sounds fine to me, it goes away (almost) automatically.
If you are paranoid then you can encrypt it or store it somewhere else and find it through a hash. This "somewhere else" is then your next point of save-enough-?
Just make sure it doesn't reach the web client.
I'm building a web system and various clients will have alternate text for default instances throughout the site. One place is the main nav but there are others. The default may be "project" but they may want to call it "event".
I'm heading down the road of calling all the terminology settings (there's a list of about 15) and creating an ArrayList that has the id and either the default or their replacement as the items in the ArrayList.
I've also got a enum key list called TermKey that has the defaults and the corresponding ID number.
Throughout the code I'll reference TermKey.Project and then do one of these things that I see as options.
1-pull the text from the session (if the client has set it to "event" then the text "event" will be waiting for the call there)
2-pull the text from the database every time I need it.
3-pull the client's list each time a page loads.
Some thoughts on the impact each way or if there is a best practice for this sort of thing would be appreciated.
The session isn't the best place for this kind of information. While yes, it is user-bound, the session state is really a repository for user-bound, session-bound information. What you seem to have is information that really has a scope beyond session.
The best way to reflect this information is to use a custom ASP.NET Profile Provider. You would use it to expose properties for the information you need to expose, while the logic in the properties would handle setting the values to the appropriate values based on the user in your system (or, an anonymous user, if they are not authenticated).
In your case, you could cache the values and access the database as needed in the profile provider.
Then, this information is exposed through the Profile property on the HttpContext class (and through the Profile property on the HttpProfileBase class as well if you are using ASP.NET MVC).
Anyway you shouldn't call DB on every page just to get alternate text. I think it is fine to store them in session if there are not too many of them (per user)
The way I've done this in the past is to have a database type code table and then a client-specific translation table like this:
TABLE ObjectType
ObjectTypeCode
TABLE ClientObjectTypeTranslation
ClientId
ObjectTypeCode
OverrideDescription
This allows my code to always reference what I know (i.e. ObjectTypeCode) and I then join to the translation table on every query and display the override description where relevant.
Though, this may be overkill for your scenario.
Session is ok to do this if you want to persist across sessions (and it's not TOO much data). Another option would be cookies.
I'd recommend on session start, instantiate session vars in a User object property, then can reference, User.DefaultText
If this is specific to each user, you might as well use session. Don't overuse is (and only use it for small amounts of data).
Going to the database for each request can be overkill, especially if this data doesn't change often - it will be much faster to retrieve from local memory than from over the network.
Having said that, using session InProc will limit you to a single server and will not allow you to scale to a web farm.
I am developing a multilingual site and was wondering what is the best way to store the language chosen by the user?
Either via QueryString or should it be in Session..or any other options?
Another consideration not mentioned in any of the other answers, is Search Engine Friendliness. If you use a different url for each language like
http://{en|cy}.example.com/subdir/ or http://example.com/{en|cy}/subdir) then search engines can index your site in multiple languages.
I think it very much depends on how your application handles (desires to handle) the user languages. If your users have to log on to your site, then you probably have an account settings page somewhere with an appropriate user profile object or something similar behind. In such a case I guess you would save these settings on the DB, and when the user comes back to your site you get the user-information somehow (i.e. from a cookie), you load your user-profile object from the DB. The information would be kept in a session since I think that would be most suited in this case.
If your users don't have to login, so you basically cannot directly identify them, I would store the language settings in a cookie. This gives your user the value that he will always find the site in his preferred language when he comes back later (given that he doesn't delete the cookies and the cookie's lifetime is long enough).
As a third possibility you could just identify the users language according to his default browser settings (just as "regex" mentioned above).
As I said, it really depends on your application's needs. What you have to keep in mind though is that
objects stored in the session are kept on the server-side, using server memory. So don't keep useless things there in memory if you don't need them. However the session object is suited for storing data related to a user's visit and configurations.
Data stored in cookies, or the Viewstate object are send back and forth between the client browser and web server. So this causes additional traffic and may decrease the performance.
Bye
if you consider this scenario where a user has browsed a series of pages in "en" and the language info is stored in cookie session and pages have been cached (http, browser, app)..
when the language is switched by the user to "cy", a change would happen for the current page, but when the user jumps back to a page they have previously visited (where the header caches expired have not expired) it would load up the page in "en" as the querystring does not state the language - for it to serve content in that language.
unlikely that a user would want to change languages so frequently - but as a developer, its a scenraio that should be handled.
any ideas please feel free to shout.
Profile properties were created specifically to allow you to store user-specific preferences. This would be good place to store this kind of data.
There is a property that is passed when a browser makes a request that you could use. This property is referenced in your code behind by referencing:
Request.UserLanguages // returns an array
Alternatively, you could prompt the user to specify a prefered language, and save it in a cookie.
In your Page.Load handler put something like the following:
string prefLan;
if(Request.Cookies["preferedLanguage"] != null)
prefLan = Server.HtmlEncode(Request.Cookies["preferedLanguage"].Value);
Querystring is not the right place for this, unless it is read initially from the querystring and stored somewhere else.
Store it in a cookie, or if cookies are turned off, store it in session or viewstate.
Kevin's answer "profile properties" is an easy way to let an established library do the heavy lifting for you with minimal effort on your part.