4

Seems like a straitforward question but I can't quite figure it out myself...

I have an actionlink like so

Html.ActionLink( "Test", "test", new { q = "search+twitter" } )

This produces a url string as follows

http://myserver/test?q=search%2Btwitter

But i would like to preserve the plus sign (which i assume is being UrlPathEncoded) so that I get the following url

http://myserver/test?q=search+twitter

Is there an easy way to do this whilst still using Html.ActionLink ?

Stuart
  • 671
  • 7
  • 20

2 Answers2

3

After some more googling, i reworded the question in this post. Using the answer from that question I was able to put together a suitable routing extension method which i include below.

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

    public static void CustomMapRoute( this RouteCollection routes, string name, string url, object defaults, string[] namespaces )
    {
        routes.CustomMapRoute( name, url, defaults, namespaces, null );
    }

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

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

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

        if ( (namespaces != null) && (namespaces.Length > 0) )
        {
            route.DataTokens["Namespaces"] = namespaces;
        }

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

public class CustomRoute : Route
{
    public CustomRoute( string url, IRouteHandler routeHandler )
        : base( url, routeHandler ) { }

    public CustomRoute( string url, RouteValueDictionary defaults, IRouteHandler routeHandler )
        : base( url, defaults, routeHandler )
    { }

    public override VirtualPathData GetVirtualPath( RequestContext requestContext, RouteValueDictionary values )
    {
        var path = base.GetVirtualPath( requestContext, values );
        if ( path != null )
        {
            path.VirtualPath = path.VirtualPath.Replace( "%20", "+" );
        }
        return path;
    }
}

This extension is then called by the RegisterRoutes method in global.asax like so...

        routes.CustomMapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },  // Parameter defaults
            new string[] { "MyControllers" }
        );
Community
  • 1
  • 1
Stuart
  • 671
  • 7
  • 20
0

The plus sign (after encoding) represents a space before encoding.

So search+twitter will become "search twitter" on post back, and to achieve that effect, you can simply use "search twitter" in the first place:

Html.ActionLink( "Test", "test", new { q = "search twitter" } )

which will generate following url

http://myserver/test?q=search%20twitter

Hope this helps.

Bill Yang
  • 1,413
  • 17
  • 28
  • Thanks for the answer. However i actually want to have http://myserver/test?q=search+twitter as the url in my browser and I'm still stumped as to how you might achieve this. – Stuart May 21 '10 at 08:41
  • If that is your goal, one solution might be to create your own Extension Method for HtmlHelper to generate the url. – Bill Yang May 21 '10 at 17:23
  • -1: This answer basically rephrases the question, but does not propose any solution. – Yann Trevin Oct 17 '11 at 13:03