How to access pretty URL from code - servlets

I am using UrlRewriteFilter to make my URLs pretty. From within my application I frequently need to access the current URL. I do it like this:
ServletActionContext.getRequest().getRequestURI();
However this gives me the ugly version of the URL. How can I access the pretty URL before it is turned into ugly one by UrlRewriteFilter?

You can extend the URLRewriteFilter class and override the doFilter method to store the request path in request attribute (Use this attribute to access the pretty url). Later call the super.doFilter method to let URLRewriteFilter do its job.

I have found this solution here.
This worked for me:
ServletActionContext.getRequest().getAttribute(
"javax.servlet.forward.request_uri");

Related

Why adding ApiExplorer breaks Swashbuckle?

After I added
services.AddVersionedApiExplorer();
previously normally working Swashbuckle started showing blank Swagger json with default version and no endpoints in it.
It appears that ApiExplorer requires presence of ApiControllerAttribute at API controllers. So if you don't have your controllers decorated with this attribute, everything will work perfectly up to the point when you add ApiExplorer, and after that Swachbuckle will behave like there are no controllers in your project at all (apparently, that's what ApiExplorer tells it).
Decorating your controllers with [ApiController] fixes this issue.
In case you don't want to bother with writing RegExp to apply those changes for you, or even go into every single controller file to paste it manually, [assembly:ApiController] will handle all of them at once.

Using Request.Url.AbsoluteUri to construct a breadcrumb link

Inside my _layout view I have added the following link , to refresh the current page as part my breadcrumb bar:
#(aoutput == "Index" ? "Home" : aoutput)
The above is working well on my development environment , but I am not sure If using the Request.Url.AbsoulteUri is the correct way to reference the current page URL ?
AbsoluteUri includes the scheme (such as http), the host, the port, the path, query string data and the fragment. As far as I know the fragment will not be included in the current URL because it is not sent with the request (that is, it's handled by the browser client-side).
This should be fine to use and is unlikely to cause you issues. Just be aware that query string data is included, which means that if you had a (poorly-designed) data manipulation system such as /Users/Index?action=deleteMostRecentUser then the user might accidently delete users because the URI would include the action.
Alternatives are
Absolute Path: /Home/Index
Path & Query: /Home/Index?query=keyword
You can use it as you mentioned.
Better way you make a separate partial view to implement breadcrumb.
And pass wanted model from Controller side. (Or in ViewBag)
The main benefit is you'll get is better control over Logic also flexible for future changes.
Hope helps.

asp.net mvc how to manage urls/links and routing centrally (c# + js)

I keep running into problems with URLs and routing.
Couldn't find an answer on SO.
I would like to manage all of my urls/links in a single place.
This is for my C# MVC code and the js/jquery ajax code.
These urls are scattered throughout my application.
Moving to a production server needs some fixes and I don't like the fact that I need to look for all of the occurrences in the application.
I don't mind fixing this once - but I would like to do it only once.
Any ideas how to manage all of these links/urls as a group will be very appreciated.
Be happy ad enjoy life, Julian
Consider using T4MVC
You could use Html.ActionLink or
Html.BuildUrlFromExpression(c => c.ControllerAction())
Depends, if you have application reading off certain urls and those urls changed once in a while. then you might want to consider putting all those urls into a database table/etc and retrieve them using specific key.
that way, when your url changed, all you need to do is to change the url on your database and all your application will still be running fine.
Urls should be managed in a single place: the RegisterRoutes static method in Global.asax. In absolutely every other part of your application you should use Html helpers when dealing/generating urls. This way you will never have problems because helpers take into account your routing system.
So instead of writing:
$('#foo').click(function() {
$('#result').load('/mycontroller/myaction');
return false;
});
you use an HTML helper to generate this foo:
<%: Html.Action("foo", "myaction", "mycontroller") %>
and then:
$('#foo').click(function() {
$('#result').load(this.href);
return false;
});
Never hardcode a single url in your application except of course in global.asax which is the only centralized place urls should be defined. So basically every time you find yourself writing something of the form /foo/bar in some other part than global.asax you are doing it wrong.

Problem passing parameters via Iframe in IE

I'm trying to execute an HTTP GET from my website to another website that is brought in via iframe.
On Firefox, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it works.
On IE, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it doesn't work...
Is there something about IE that doesn't let you pass parameters through an iframe in the querystring?
I've tried refreshing the iframe in IE, I've tried refreshing my page & the iframe in IE, and I've tried copying the url and re-pasting it into the iframe src (forcing it to refresh as if I just entered it into the address bar for that iframe window). Still no luck!
Anyone know why this is happening, or have any suggestions to try to get around this?
Edit: I cannot give a link to this because the site requires a password and login credentials to both our site and our vendor's site. Even though I could make a test account on our site, it would not do any good for the testing process because I cannot do the same for the vendor site. As for the code, all it's doing is creating the src from the backend code on page load and setting the src attribute from the back end...
//Backend code to set src
mainIframe.Attributes["src"] = srcWeJustCreated;
//Front end iframe code
<iframe id="mainIframe" runat="server" />
Edit: Problem was never solved. Answer auto accepted because the bounty expired. I will re-ask this question with more info and a link to the page when our site is closer to going live.
Thanks,
Matt
By the default security settings in IE query parameters are blocked in Iframes. On the security tab under internet options set your security level to low. If this fixes your problem then you know that is your issue. If the site is for external customers then expecting them to turn down their security settings is probably unreasonable, so you may have to find a work around.
Let's say your site is www.acme.com and the iframe source is at www.myvendor.com.
IIRC, most domain-level security settings don't care about the hostname, so add a DNS CNAME to your zone file for myvendor.acme.com, pointed back to www.myvendor.com. Then, in your IFRAME, set the source using your hostname alias.
Another solution might be to have your Javascript set the src to a redirector script on your own server (and, thus, within your domain). Your script would then simply redirect the IFRAME to the "correct" URL with the same parameters.
If it suits you, you can communicate between sites with fragment identifiers. You can find an article here: http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html
What BYK said. I think what's happening is you are GETting a URL that is too large for IE to handle. I notice you are trying to send variable named src, which is probably very long, over 4k. I ran into this problem before, and this was my code. Notice the comment about IE. Also notice it causes a problem with Firefox then, which is addressed in another comment.
var autoSaveFrame = window.frames['autosave'];
// try to create a temp form object to submit via post, as sending the browser to a very very long URL causes problems for the server and in IE with GET requests.
var host = document.location.host;
var protocol = document.location.protocol;
// Create a form
var f = autoSaveFrame.document.createElement("form");
// Add it to the document body
autoSaveFrame.document.body.appendChild(f);
// Add action and method attributes
f.action = protocol + '//' + host + "/autosave.php"; // firefox requires a COMPLETE url for some reason! Less a cryptic error results!
f.method = "POST"
var postInput = autoSaveFrame.document.createElement('input');
postInput.type = 'text'
postInput.name = 'post';
postInput.value = post;
f.appendChild(postInput);
//alert(f.elements['post'].value.length);
// Call the form's submit method
f.submit();
Based on Mike's answer, the easiest solution in your case would be to use "parameter hiding" to convert all GET parameters into a single URL.
The most scalable way would be for each 'folder' in the URL to consist of the parameter, then a comma, then the value. For example you would use these URLs in your app:
http://example.com/app/param,value/otherparam,othervalue
http://example.com/app/param,value/thirdparam,value3
Which would be the equivalent of these:
http://example.com/app?param=value&otherparam=othervalue
http://example.com/app?param=value&thirdparam=value3
This is pretty easy on Apache with .htaccess, but it looks like you're using IIS so I'll leave it up to you to research the exact implementation.
EDIT: just came back to this and realised it wouldn't be possible for you to implement the above on a different domain if you don't own it :p However, you can do it server-side like this:
Set up the above parameter-hiding on your own server as a special script (might not be necessary if IE doesn't mind GET from the same server).
In Javascript, build the static-looking URL from the various parameters.
Have the script on your server use the parameters and read the external URL and output it, i.e. get the content server-side. This question may help you with that.
So your iframe URL would be:
http://yoursite.com/app/param,value/otherparam,othervalue
And that page would read and display the URL:
http://externalsite.com/app?param=value&otherparam=othervalue
Try using an indirect method. Create a FORM. Set its action parameter to the base url you want to navigate. Set its method to POST. Set its target to your iframe and then create the necessary parameters as hidden inputs. Finally, submit the form. It should work since it works with POST.

How do I determine if an asp.net url has been "rewritten"?

I'm using http://urlrewriter.net/ to rewrite urls at my website. For example, I'm rewriting:
http://www.example.com/schedule.aspx?state=ca
to
http://www.example.com/california.aspx
What I'm trying to do (for SEO purposes) to to dynamically add the meta tag:
<meta name="robots" content="noindex,follow" />
only to the page that hasn't been rewritten. This is because I want both URLs to work, but only the rewritten one to be indexed by search engines.
How do I determine which version of the page has been requested?
EDIT
Answers below suggest a 301 redirect instead of using a meta tag. Maybe I'll do this, but I still want to know the answer to the underlying question... how do I know if the page has been rewritten?
personally, I would 301 redirect from the un-rewritten one to the re-written one, and only use the single copy of the page. It is easier for users, and from an SEO perspective, you have 1 copy of the content.
If you need to do this you can probably do something like:
<add header="X-WasRewritten" value="true" />
And you can check for the header in your view and add the robots meta tag if you need it.
This will get returned to the client too, so if you want to hide that you can write a CustomAction (http://urlrewriter.net/index.php/support/reference/actions/custom-action) which will set some kind of state value in your request.
However, having two URIs for the same resource is something I would not recommend. I suggest you just keep the one representation. If you're worried about invalidating old bookmarks you can set the old one to redirect to the new one.
Further to chakrit's answer, it looks like UrlRewriter.NET stores the original URL in the HttpContext, in a key called UrlRewriter.NET.RawUrl. So, you could try something like:
bool isPageRewritten =
!string.IsNullOrEmpty(HttpContext.Current.Items["UrlRewriter.NET.RawUrl"]);
Most obvious method is to use the Request.Url object in your page to get information about the URL and query string. For example:
if (Path.GetFileName(Request.Url.FilePath) == "schedule.aspx")
//Not rewritten
else
//rewritten
I think that's the job of HttpContext.Current.Items.
You can save the "Redirection" in HttpContext.Current.Items and then in your pages, you can check it for a certain added value.
I believe you can add hooks to urlrewriter.net that could do it, something alongs:
HttpContext.Current.Items["Redirected_From"] = currentUrlHere;
And then in your webpages, you could check it by:
if (!string.IsNullOrEmpty(HttpContext.Current.Items["Redirected_From"]))
// the page's been redirected, do something!
else
// no it's visited normally.
I have long since left it for the ASP.NET Routing framework in .NET 3.5 SP1, it is better than urlrewriter.net IMO.

Resources