4

I am working on an application with ASP.NET MVC Routing + AngularJS routing.

My URL lookslike:

https://example.com/Request/#/Search/Request/123

when I breakdown this (http://example.com/Request) is handled by ASP.NET MVC routing. i.e. (Area = Request, controller = "Default", action = "Index")

(#/Search/Request/123) is handled by AngularJS routing.

This works perfectly when I am on http://localhost:8080/

The issue is when I deploy this application to https://example.com/

In this case, If user clicks on above link (received via email),IE 9 recognizes only (https://example.com/Request/") and the server never gets (#/Search/Request/123).

We have enterprise SSO implemented on web server. SSO client intercepts http request and uses URL to redirect back to requested page after authentication.

if # fragment is not sent as part of http request url, sso is not able to redirect back to same page.

I believe this to be a common scenario/issue. I would keep changing the URL scheme as last resort. e.g. (# to !).

How to solve this?

Darshan Joshi
  • 362
  • 1
  • 11
  • If Angular is handling the #/Search/Request/123 segment of the URL, why should you expect to receive it on the server end? – sq33G Apr 21 '15 at 19:40

3 Answers3

2

Just found a blog that dealt with this issue exactly:

http://codetunnel.io/how-to-persist-url-hash-fragments-across-a-login-redirect/

He offers two ideas:

When the page loads there simply needs to be some JavaScript that accesses the hash fragment and appends it to the redirect URL in the hidden field. Here's an example using JQuery for simplicity

$(function () {
  var $redirect = $('[name="redirect"]');
  $redirect.val($redirect.val() + window.location.hash);
});

Or, alternatively

Instead of appending the hash fragment to the hidden field value, you could avoid sending it to the server at all and simply append it to the form action URL.

$(function () {
  var $loginForm = $('#loginForm');
  var actionUrl = $loginForm.attr('action');
  $loginForm.attr('action', actionUrl + window.location.hash);
});
sq33G
  • 3,320
  • 1
  • 23
  • 38
  • Hi @sq33G, So, I need to: 1. Have a landing page for this URL 2. This landing page should be out of SSO 3. This landing page should set # fragment to one of the hidden form fields (may be created using jquery) 4. at last this landing page should redirect to another url (which does not have #fragment) 5. This another url on server, should read hidden field set using jquery and return the same field with same value on client 6. On client on document.ready / window.load, there should be another jquery, that read this hidden field and adds # fragment to window.location . Am I correct? – Darshan Joshi Apr 22 '15 at 13:11
  • Honestly, I haven't tried to implement this myself. But I think you're headed in the right direction, except that you probably won't be running any jquery on your server. – sq33G Apr 22 '15 at 19:49
  • Thanks @sq33G! I will update this question once we decide and implement one of the suggestions. – Darshan Joshi Apr 23 '15 at 06:18
  • Does not seem to work for IE<=9. The browser does not preserve the hash-tags after redirect. :( – user2173353 May 26 '15 at 14:31
0

I would remove ugly URL's from your application all together.

This article will walk you through removing ugly URL's in a asp.net-mvc project. It will also ensure that you have your RouteConfig.cs setup correctly.

http://www.codeproject.com/Articles/806500/Getting-started-with-AngularJS-and-ASP-NET-MVC-P

Harbinger
  • 594
  • 1
  • 8
  • 18
0

Fragments (the part of the URL after the #) are not necessarily sent to the server-side by the browser. They are for client-side usage only (navigating to a specific location in the document, JavaScript support).

RFC 2396 section 4.1:

When a URI reference is used to perform a retrieval action on the identified resource, the optional fragment identifier, separated from the URI by a crosshatch ("#") character, consists of additional reference information to be interpreted by the user agent after the retrieval action has been successfully completed. As such, it is not part of a URI, but is often used in conjunction with a URI.

(emphasis added)

Therefore, the URL scheme you came up with will not work reliably unless you change the # to another character. Alternatively, you could use JavaScript to transfer the information from the fragment in an input that will be reliably passed back to the server. But do note that solution will only work if JavaScript is enabled in the browser, so it is (also) not a 100% reliable solution that will work with all clients.

Either way, using a URL without a fragment is a more reliable approach and IMO a better design choice if you expect that part to be interpreted by the server.

Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212