8

I have the following routing code:

routes.MapRoute(
            "email-validated/{sessionId}",
            "email-validated/{sessionId}",
            new { controller = "User", action = "EmailValidated", sessionId = UrlParameter.Optional }
            );

When I hit the route w/ something that is url encoded it won't match the route for %2f, %2b and some other escaped characters. It also won't match for non url encoded (things w/ + etc) For instance

This works:

email-validated/XQiKC6KMM%2cmko4nOvzGRwPu9oaZFoCtXsFFJg3ZTf9S5rsBbLGjnz3FN3SJ0apEZcqK1PIcCY28mRMykB39XnFLKaL7390CDfLZiV77cso

This doesn't work ( containts %2f etc):

email-validated/XQiKC6KMM%2fmko4nOvzGRwPu9oaZFoCtXsFFJg3ZTf9S5rsBbLGjnz3FN3SJ0apEZcqK1PIcCY28mRMykB39XnFLKaL7390CDfLZiV77cso

This doesn't work (contains + etc)

email-validated/XQiKC6KMM+mko4nOvzGRwPu9oaZFoCtXsFFJg3ZTf9S5rsBbLGjnz3FN3SJ0apEZcqK1PIcCY28mRMykB39XnFLKaL7390CDfLZiV77cso
3
  • how are you generating this SessionId? Commented Aug 29, 2011 at 2:48
  • You should use a GUID instead of that string. It appears very random and has the chance to not only contain badly encoded characters but also <> characters invalidating the request. Commented Aug 29, 2011 at 2:50
  • the session is a random string that is then base 64 encoded and then HttpUtilty.UrlEncoded. I am working with porting a legacy site to mvc 3 and it would be extremely difficutly to re-code how session ids work unfortunately so need a solution for this :( Commented Aug 29, 2011 at 3:29

4 Answers 4

9

If you can, you need to make your sessionId URL safe. The sessionId is Base64 encoded, and there are three URL problem characters in Base64, "/", "+" and "=". Use the following to encode your sessionId when creating your link:

    public string ToUrlSafeBase64String(string Base64String)
    {
        // avoid any slashes, plus signs or equal signs
        // the following makes this base64 string url safe
        Base64String = Base64String.Replace("/", "_");
        Base64String = Base64String.Replace("+", "-");
        return Base64String.Replace("=", String.Empty);
    }

Then, use the following to re-create the original Base64 encoded string:

    public string FromUrlSafeBase64String(string Base64String)
    {
        // add back any slashes, plus signs or equal signs
        // the following makes this url safe string a base64 string
        Base64String = Base64String.Replace("_", "/");
        Base64String = Base64String.Replace( "-", "+");
        return Base64String.PadRight(Base64String.Length + (4 - Base64String.Length % 4) % 4, '=');
    }
Sign up to request clarification or add additional context in comments.

2 Comments

I think this is the better solution of the two.
The other answer is like saying if your car makes a strange noise, to leave it alone and stop driving it. This one says open the bonnet and fix X. Thanks, exactly what I needed!
5

It looks like the routing path handles escaped /'s and +'s weirdly. Try passing it in as a query string argument instead.

Make your endpoint:

routes.MapRoute(
            "email-validated",
            "email-validated",
            new { controller = "User", action = "EmailValidated" }
            );

Call it with a request like:

email-validated/?sessionId=XQiKC6KMM%2fmko4nOvzGRwPu9oaZFoCtXsFFJg3ZTf9S5rsBbLGjnz3FN3SJ0apEZcqK1PIcCY28mRMykB39XnFLKaL7390CDfLZiV77cso

And then change your function from

EmailValidatedFunction(string sessionId)
{
   //...do stuff with sessionId here
}

to:

EmailValidatedFunction()
{
   string sessionId = Request["sessionId"];
   //...do stuff with sessionId here
}

Comments

0

Here's the solution I've found to allow url encoded characters like the forward slash %2f in Asp.Net MVC urls.

Add the following to the Application_BeginRequest method of your Global.asax file:

var realUrl = Request.ServerVariables["HTTP_URL"];
Context.RewritePath(realUrl);

Since this happens before MVC routing, you will be able to do what you originally wanted to do.

Just remember that you'll need to manually decode the parameters in your Action Methods to get their actual value (since we're preventing the framework from doing so).

Comments

0

you can use System.Web.HttpServerUtility.UrlTokenEncode (from http://brockallen.com/2014/10/17/base64url-encoding/#comments)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.