How to add multiple *.sitemap files to mvcsitemapprovider during session start - asp.net-mvc

I want to associate multiple sitemaps to mvcsitemapprovider during session_start event as sitemaps names and locations are retrieved based upon the type of client/user. But, according to documents related to mvcsitemapprovider, all *.sitemaps are getting associated to mvcsitemapprovider during application start. Is there any way, I can provide this functionality using this control?

There is no built-in per session functionality, but you could implement your own ICacheProvider to handle this requirement. Also see MvcSiteMapProvider 4.0 - Extending the Cache and Multiple SiteMaps in One Application for more guidance.
Do note that the primary reason this doesn't exist out of the box is because it would be extremely memory intensive and would not scale to very many users. Unless your navigation is completely different per user, I wouldn't recommend using this approach. A better alternative is to use the preservedRouteParameters approach to force some route values to match any value (in your case userid or clientid), and then use ISiteMapNodeVisibilityProvider, SiteMapTitleAttribute, and/or manual updating of SiteMapNode properties per request to control the visibility of the node.
Please see my open question here and explain to me why you would want to do this on GitHub, as it renders most of the features useless: https://github.com/maartenba/MvcSiteMapProvider/issues/16#issuecomment-22229604

Related

MVC beginner - Advice on how to persist a user selection for use throughout the site

I have an application which is centered around data per 'team'. A user belongs to a team and if they log in they only see that team's data.
However, I now have super users who essentially belong to more than one team. These users should be able to log in to the system and then immediately choose which team they are interested in. From then on they will essentially view/create data against that selected team. They should also have the option to go and change what team they are viewing at any time.
I've established that the user would like to be able to have multiple tabs open and be viewing a different team in each tab.
I'm struggling to work out the best way to accomplish this with .NET MVC while keeping it as stateless and testable as possible.
I've been reading up on the different ways to persist data - session state and cookies seem to get a bad rep in MVC. TempData, ViewBag seem to focus on just persisting data for one request.
I wouldn't have thought that this is an uncommon requirement in an application - are there known patterns for dealing with this in MVC which I have missed?
So far I'm trying to create a partial view which I can show on each page to let the user see what team they are viewing the site as, and change it from there.
Any advice is appreciated!
If you want to let your superuser view multiple teams data then you'll want to pass the team information in on the request, on the query string or as something that looks like a restful url:
/blueteam/members
In fact it would be extra work to track this in a stateful manner as you'd have track user, team, and ui element when a superuser can view multiple team data at once.
I'd say passing the information in on every request is a pretty standard approach to your situation.
The tricky part of the stateless approach is decorating all your internal application links with the team information without too much extra work. Relative links can be your friends here. So a link to the bug page for a team might be to simply "bugs", picking up the team name higher in the uri path. If you are creating something that looks like a one page application it's easy enough to store the team info on the client.
If you don't want team members to see data for other team members, you can set up guard functions that check for team membership for certain classes of users before rendering a view.

How to setup custom id-field in DB4O

I've read the documentation and samples multiple times and can't find out how to do this.,
I'm trying to wire up DB4O to use my own custom Id field. based on the documentation you can define your own IDs but as far as I can tell they won't replace Db4o's internal IDs, As in it won't actually use those Ids to identify the objects.
Basically all the examples do are tell Db4o to generate some sort of unique id and index it, I don't see anywhere on how to tell it that this is the ID that you should use.
Is it possible to have our own IDs on our model replace the internal IDs used to keep track of the relationships?
we need to have our own Ids since our system relies heavily on REST.
There no direct support for this. You need to create your own mechanism.
Simplest way: Use Guid on .NET. Or use a UUID in Java. In Java: Add UUID-Support: configuration.common().add(new UuidSupport());
Use callback to create new id's. Doesn't not work in TCP client/server.
See also this page.
Side note: You build a REST app. How many request does it need to handle? db4o is internally inherently single threaded. It can only handle a very limited load.

Rails - Store unique data for each open tab/window

I have an application that has different data sets depending on which company the user has currently selected (dropdown box on sidebar currently used to set a session variable).
My client has expressed a desire to have the ability to work on multiple different data sets from a single browser simultaneously. Hence, sessions no longer cut it.
Googling seems to imply get or post data along with every request is the way, which was my first guess. Is there a better/easier/rails way to achieve this?
You have a few options here, but as you point out, the session system won't work for you since it is global across all instances of the same browser.
The standard approach is to add something to the URL that identifies the context in which to execute. This could be as simple as a prefix like /companyx/users instead of /users where you're fetching the company slug and using that as a scope. Generally you do this by having a controller base class that does this work for you, then inherit from that for all other controllers that will be affected the same way.
Another approach is to move the company identifying component from the URL to the host name. This is common amongst software-as-a-service providers because it makes sharding your application much easier. Instead of myapp.com/companyx/users you'd have companyx.myapp.com/users. This has the advantage of preserving the existing URL structure, and when you have large amounts of data, you can partition your app by customer into different databases without a lot of headache.
The answer you found with tagging all the URLs using a GET token or a POST field is not going to work very well. For one, it's messy, and secondly, a site with every link being a POST is very annoying to work with as it makes navigating with the back-button or forcing a reload troublesome. The reason it has seen use is because out of the box PHP and ASP do not have support routes, so people have had to make do.
You can create a temporary database table, or use a key-value database and store all data you need in it. The uniq key can be used as a window id. Furthermore, you have to add this window id to each link. So you can receive the corresponding data for each browser tab out of the database and store it in the session, object,...
If you have an object, lets say #data, you can store it in the database using Marshal.dump and get it back with Marshal.load.

Why would Google Search use client-side URL parameters?

Yesterday morning I noticed Google Search was using hash parameters:
http://www.google.com/#q=Client-side+URL+parameters
which seems to be the same as the more usual search (with search?q=Client-side+URL+parameters). (It seems they are no longer using it by default when doing a search using their form.)
Why would they do that?
More generally, I see hash parameters cropping up on a lot of web sites. Is it a good thing? Is it a hack? Is it a departure from REST principles? I'm wondering if I should use this technique in web applications, and when.
There's a discussion by the W3C of different use cases, but I don't see which one would apply to the example above. They also seem undecided about recommendations.
Google has many live experimental features that are turned on/off based on your preferences, location and other factors (probably random selection as well.) I'm pretty sure the one you mention is one of those as well.
What happens in the background when a hash is used instead of a query string parameter is that it queries the "real" URL (http://www.google.com/search?q=hello) using JavaScript, then it modifies the existing page with the content. This will appear much more responsive to the user since the page does not have to reload entirely. The reason for the hash is so that browser history and state is maintained. If you go to http://www.google.com/#q=hello you'll find that you actually get the search results for "hello" (even if your browser is really only requesting http://www.google.com/) With JavaScript turned off, it wouldn't work however, and you'd just get the Google front page.
Hashes are appearing more and more as dynamic web sites are becoming the norm. Hashes are maintained entirely on the client and therefore do not incur a server request when changed. This makes them excellent candidates for maintaining unique addresses to different states of the web application, while still being on the exact same page.
I have been using them myself more and more lately, and you can find one example here: http://blixt.org/js -- If you have a look at the "Hash" library on that page, you'll see my implementation of supporting hashes across browsers.
Here's a little guide for using hashes for storing state:
How?
Maintaining state in hashes implies that your application (I'll call it application since you generally only use hashes for state in more advanced web solutions) relies on JavaScript. Without JavaScript, the only function of hashes would be to tell the browser to find content somewhere on the page.
Once you have implemented some JavaScript to detect changes to the hash, the next step would be to parse the hash into meaningful data (just as you would with query string parameters.)
Why?
Once you've got the state in the hash, it can be modified by your code (or your user) to represent the current state in your application. There are many reasons for why you would want to do this.
One common case is when only a small part of a page changes based on a variable, and it would be inefficient to reload the entire page to reflect that change (Example: You've got a box with tabs. The active tab can be identified in the hash.)
Other cases are when you load content dynamically in JavaScript, and you want to tell the client what content to load (Example: http://beta.multifarce.com/#?state=7001, will take you to a specific point in the text adventure.)
When?
If you had a look at my "JavaScript realm" you'll see a border-line overkill case. I did it simply because I wanted to cram as much JavaScript dynamics into that page as possible. In a normal project I would be conservative about when to do this, and only do it when you will see positive changes in one or more of the following areas:
User interactivity
Usually the user won't see much difference, but the URLs can be confusing
Remember loading indicators! Loading content dynamically can be frustrating to the user if it takes time.
Responsiveness (time from one state to another)
Performance (bandwidth, server CPU)
No JavaScript?
Here comes a big deterrent. While you can safely rely on 99% of your users to have a browser capable of using your page with hashes for state, there are still many cases where you simply can't rely on this. Search engine crawlers, for example. While Google is constantly working to make their crawler work with the latest web technologies (did you know that they index Flash applications?), it still isn't a person and can't make sense of some things.
Basically, you're on a crossroads between compatability and user experience.
But you can always build a road inbetween, which of course requires more work. In less metaphorical terms: Implement both solutions so that there is a server-side URL for every client-side URL that outputs relevant content. For compatible clients it would redirect them to the hash URL. This way, Google can index "hard" URLs and when users click them, they get the dynamic state stuff!
Recently google also stopped serving direct links in search results offering instead redirects.
I believe both have to do with gathering usage statistics, what searches were performed by the same user, in what sequence, what of the search results the user has followed etc.
P.S. Now, that's interesting, direct links are back. I absolutely remember seeing there only redirects in the last couple of weeks. They are definitely experimenting with something.

How to pass context around in a ASP.NET MVC web app

Ok, I'm a newbie to ASP.NET web apps... and web apps in general. I'm just doing a bit of a play app for an internal tool at work.
given this tutorial...
http://www.asp.net/learn/mvc-videos/video-395.aspx
The example basically has a global tasklist.
So if I wanted to do the same thing, but now I want to maintain tasks for projects. So I now select a project and I get the task list for that project. How do I keep the context of what project I have selected as I interact with the tasks? Do I encode it into the link somehow? or do you keep it in some kind of session data? or some other way?
As it sounds like you are having multiple projects with a number of tasks each, it would be best practise to let the project be set in the URL. This would require a route such as "/projects/{project}/tasks". It follows the RESTful URL principle (i.e. the URL describes the content).
Using session state will not work if a user possibly have different projects open in multiple browser windows. Let's say I am logging into your system and a selecting two projects opening in two tabs. First the session is set to the project of the first opened tab, but as soon the second tab has loaded, the session will be overwritten to this project. If I then do anything in the first tab, it will be recorded for the second project.
I use:
Session state for state that should last for multiple requests, e.g. when using wizards. I'd be careful not to put too much data here though as it can lead to scalability problems.
TempData for scenarios where you only want the state to be available for the next request (e.g. when you are redirecting to another action and you want that action to have access to the state, but you don't want it to hang around after that)
Hidden form fields [input type="hidden"] for state that pertains to the form data and that I want the the controller to know about, but I don't want that data displayed. Also can be used to push state to the client so as not to overburden server resources.
ok, From what I can tell, the best option seems to be to save it into the Session data
RESTful URLs, hidden fields, and session cookies are your friends.

Resources