brenjt
brenjt

Reputation: 16297

Get current fragment in Route, ASP.net MVC

Is there away to get the current fragment from a route that was issued via action link. This is how I am getting the action from the route.

string currentAction = requestContext.RouteData.Values["action"] as string ?? "index";

Can I do something similar to this?

string currentFragment = requestContext.RouteData.Values["Fragment"] as string ?? "";

Upvotes: 5

Views: 5632

Answers (3)

YazanGhafir
YazanGhafir

Reputation: 884

I have a workaround for you, but first of all lets get more into the problem.

The strings after the hash symbol which are called Fragment values are not query parameters but they are strings to be read by the client-side (living in the browser) and the server cannot read them because they are not sent to the server by the browser.

Some authentication providers like Google and Azure send the access token as Fragment value for security reasons so that they are not transferred over the internet after they get sent as direct response from the authentication provider.

The only way you can come around that is to use javascript to convert the fragment values to query parameters by replacing the '#' with '?' and redirecting to the endpoint in your server controller.

I suppose the easiest way is to handle all that from server, meaning you get get the request in server, send a javascript code to the browser on the fly, that replaces the '#' into '?' and redirects to your second endpoint which reads the token as strong parameter.

Here how you can do it in ASP.NET Core 3.1:

[AllowAnonymous]
[HttpGet("authredirect")]
[Produces("text/html")]
public virtual ContentResult ConvertUrlFragmentToQueryParamThenRedirect()
{
  return Content("<html><script>window.location.href=window.location.href.replace('#', '?').replace('authredirect', 'authparams')</script></html>", "text/html");
}

[AllowAnonymous]
[HttpGet("authparams")]
public virtual void GetAccessToken([FromQuery] string access_token)
{
  // now you have your access token server side here
}

Please remember to set your redirectUrl to the correct one, in this case 'YOUR REDIRECT URL/authredirect'.

Upvotes: 0

user151323
user151323

Reputation:

As it has already been pointed out that is not possible. Document fragments (the string after the hash as you call it) are intended for the browsers only to correctly position the viewport. They have no meaning for the server and therefore are not transmitted there.

There is however a workaround you can use. Repeat the fragment as part of your url to make it accessible for the server.

Look at the permalink to the answers in this question. For instance, the link to my answer looks like this:

http://stackoverflow.com/questions
/6285833/get-current-fragment-in-route-asp-net-mvc/6286097#6286097

See how the value 6286097 is duplicated as the last route parameter. It's intentional. You can use this technique as well.

P.S. The fragment must point to an identifier in the document (id of some HTML element). At least in XHTML only identifiers work as fragments. Valid ids may not begin with a digit therefore instead of #6286097 use something like #answer-6286097.

P.S.#2. Do not use any JavaScript trickery to get around this limitation. Basic site functionality and design must work without JavaScript - don't listen to anyone who tells you otherwise. Fragments obviously belong to the basic tool box. Use JavaScript only for advanced interactivity.

Upvotes: 3

Darin Dimitrov
Darin Dimitrov

Reputation: 1039398

No, you can't do anything like this. The fragment (everything that follows the # sign in an url) is never sent to the server by the browser, so the sole fact of talking about getting the url fragment server side simply doesn't make sense.

So if you have the following url: http://example.com/foo/bar?key1=value1#abc the server will never be able to fetch abc simply because the client will never send it.

Upvotes: 17

Related Questions