views:

366

answers:

3

I need to maintain the querystring in all pages in my asp.net mvc(C#) application.

For ex.: I will call a page www.example.com?Preview=True. The querystring should be maintained whatever the page i click in www.example.com. i.e. When i click About us page in www.example.com, the url should be www.example.com/AboutUs?Preview=True

How can i achieve this? Whats the best place to do this common operation.?

A: 

You could create a view Helper that appends the existing query string onto any links you create with your new helper.

This may help

You might be better storing this information in session.

Rigobert Song
A: 

Maybe you need a custom route?:

public class PreviewRoute : System.Web.Routing.Route
{
    ...

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        var preview = System.Web.HttpContext.Current.Session["Preview"];

        if (!values.ContainsKey("Preview"))
            values.Add("Preview", preview);

        var path = base.GetVirtualPath(requestContext, values);

        return path;
    }
}

}

Set Session["Preview"] at any time and you will get all your urls with ?Preview=True:

System.Web.HttpContext.Current.Session.Add("Preview", true);

UPDATED:

Use this route in the Global.asax.cs:

routes.Add("Default",
    new PreviewRoute("{controller}/{action}/{id}", new MvcRouteHandler()) {
        Defaults = new RouteValueDictionary(
            new { controller = "Home", action = "Index", id = "" }
        )
    }
);

instead of:

routes.MapRouteLowercase(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

Also you can try this extension:

public static class CustomRouteExtensions
{
    public static void MapPreviewRoute(this RouteCollection routes, string name, string url, object defaults) {
        routes.MapPreviewRoute(name, url, defaults, null);
    }

    public static void MapPreviewRoute(this RouteCollection routes, string name, string url, object defaults, object constraints) {
        if (routes == null) {
            throw new ArgumentNullException("routes");
        }

        if (url == null) {
            throw new ArgumentNullException("url");
        }

        var route = new PreviewRoute(url, new MvcRouteHandler()) {
            Defaults = new RouteValueDictionary(defaults),
            Constraints = new RouteValueDictionary(constraints)
        };

        if (String.IsNullOrEmpty(name)) {
            routes.Add(route);
        }
        else {
            routes.Add(name, route);
        }
    }
}

In Global.asax.cs:

routes.MapPreviewRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);
eu-ge-ne
Where to use this custom route?
Prasad
is there any other way except session? Because when i integrated it, i have few issues.. i.e. When the user clicks the preview, it shows the second website in preview with all controls disabled. And at the same time, when the user views it as live, even then the controls will be disabled, as it has the "Preview" key in session
Prasad
If the user switches from Preview to Live mode, you would want to remove that "Preview" key from the session.
jrista
A: 

An excellent direction from @eu-ge-ne.

I have used the idea of custom route from @eu-ge-ne to add the route value to every url and used a basecontroller to handle the Preview key in session.

if ((requestContext.HttpContext.Request.QueryString != null &&
     requestContext.HttpContext.Request.QueryString["Preview"] != null &&
     requestContext.HttpContext.Request.QueryString["Preview"].ToString() =="True") ||
     (requestContext.HttpContext.Request.UrlReferrer != null &&
     requestContext.HttpContext.Request.UrlReferrer.ToString().Contains("Preview=True")))
    {
         //Add the preview key to session
    }
    else
    {
         //Remove the preview key to session
    }

I have used the above code in the Initialize method of the base controller. This way the preview key will in session if the querystring has Preview, else it removes from the session.

Thanks to @eu-ge-ne once again.

Prasad