converting virtual path to actual web path in ASP.NET - asp.net

I have a virtual path (example: "~/Images/Banner.jpg") and I want to make that an absolute web path (example: "/ApplicationRoot/Images/Banner.jpg"). There is a method that will do this, I believe in a class called something like HTTPUtility or similar name. Though ever time I need this method, it takes me hours searching for it. It would be greatly appreciated if someone could post the proper method to do this so I can favorite this for easy access in the future.
Thank you very much.

System.Web.VirtualPathUtility.ToAbsolute("yourRelativePath");
There you go :)

There are various ways that are available in ASP.NET that we can use to resolve relative paths to absolute Urls -
1) Request.ApplicationPath
2) System.Web.VirtualPathUtility
3) Page.ResolveUrl
4) Page.ResolveClientUrl
Here's a article that explains the difference between the various ways to resolving paths in ASP.NET -
Different approaches for resolving URLs in ASP.NET

Control.ResolveClientUrl(url)
or
Control.ResolveUrl(url)
Whichever one you need (honestly I dont know the difference, as both seem to return mostly the same, perhaps someone can illuminate me :) ).

Related

Force case-sensitive routing in ASP.NET MVC

This question has been asked in a similar but not identical fashion (and not resolved to my satisfaction) previously on Stack Overflow and elsewhere.
Coming from a linux-world, I want to use ASP.NET MVC but avoid identical but differently-cased routes from resolving to the same page. I do not want to force all routes to be 100% lowercase.
e.g. I want /Home/Something to be a valid route and /Home/somethingElse to also be a valid route, but not /Home/something or /home/somethingelse, given two functions called Something and somethingElse in the HomeController.
I can't find any way of doing this from within the RegisterRoutes function, but maybe I'm missing something obvious? I can answer this easily enough by adding code to each Controller function, but I'm obviously trying to avoid doing that.
Optimally, the solution would involve catching all permutations of a particular route, then 301 redirecting any that do not exactly match the case of the controller's function.
I was unable to find any way of doing this after extensive searching. Basically, case-sensitivity and IIS/ASP.NET apparently do not go together.
We're now using a bit of a kludge to solve this. The code has been opensourced (MIT license) on github: NeoSmart Web Toolkit, in particular, this file containing the SEO redirect code.
Using it is easy enough: each GET method in the controller classes needs to add just this one line at the start:
Seo.SeoRedirect(this);
The SEO rewrite class automatically uses C# 5.0's Caller Info attributes to do the heavy lifting, making the code above strictly copy-and-paste.
Ideally, I would love to find a way to turn that line of code into an attribute. For instance, prefixing the controller methods with [CaseSensitive] would automatically have the same effect as writing in that line, but alas, I do not (yet) know how to do this.
I also can't find any way of figuring this out with the Routing class/structures. That's some opaque code!

Problem with differentiation of pathparams

I have problem with Jax-rs #Path variable, I need to differentiate the following two pathparams
#Path({domain}/{id})
#Path({domain}/{filename})
sample url for both:
1. http://localhost:8080/in.com/lrth09erdfgwe
2. http://localhost:8080/in.com/lrth09erdfgwe.xml
I think we need to use regex in pathparam! I tried it but failed to get it!
I'm using this application in Resteasy integration with spring-mvc.
Plz advice on this issue!
Cheers!
You control the matching of path parameter by putting inside the parameter a colon and then an RE pattern to match it, like this (where the RE is .+[.].+, which matches anything so long as it has at least one dot somewhere in the middle):
#Path("{domain}/{filename:.+[.].+}")
I use this in one of my services (which uses Apache CXF, but I believe this is a feature of all JAX-RS implementations). Have a care though! You can match path separators with this, which can make things very confusing. (I think you might be better to change the structure of the URIs so that there is no ambiguity, e.g., {domain}/id/{id} and {domain}/files/{filename}. I bet your clients will grok that much more rapidly.)

Token replacement

I currently implement a replace function in the page render method which replaces commonly used strings - such as replace [cfe] with the root to the customer front end. This is because the value may be different based on the version of the site - for example the root to the image folder ([imagepath]) is /Images on development and live, but /Test/Images on test.
I have a catalogue of products for which I would like to change [productName] to a link to the catalogue page for that product. I would like to go through the entire page and replace all instances of [someValue] with the relevant link. Currently I do this by looping through all the products in the product database and replacing [productName] with the link to the catalog page for that product. However this is limited to products which exist in the database. "Links" to products which have been removed currently wont be replaced, so [someValue] will be displayed to the user. This does not look good.
So you should be able to see my problem from this. Does anyone know of a way to achieve what I would like to easily? I could use regexes, but I don't have much experience of those. If this is the easiest way, using "For Each Match As String In Regex.Matches(blah, blah)" then I am willing to look further into this.
However at some point I would like to take this further - for example setting page layouts such as 3 columns with an image top right using [layout type="3colImageTopRight" imageURL="imageURL"]Content here[/layout]. I think I could kind of do this now, but I cant figure out how to deal with this if the imageURL were, say, [Image:Product01.gif] (using regex.match("[[a-zA-Z]{0,}]") I think would match just [layout type="3colImageTopRight" imageURL="[Image:Product01.gif] (it would not get to the end of the layout tag). Obviously the above wouldn't quite work, as I haven't included double quotes in the match string or anything, but you get the general idea. You should be able to get the general idea of what I am getting at and what I am trying to do though.
Does anyone have any ideas or pointers which could help me with this? Also if this is not strictly token replacement then please point me to what it is, so I can further develop this.
Aristos - hope reexplaining this resolves the confusion.
Thanks in advance,
Regards,
Richard Clarke
#RichardClarke - I would go with Regular Expressions, they're not as terrible to learn as you might think and with a bit of careful usage will solve your problems.
I've always found this a very useful tool.
http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx
goes nicely with a cheat sheet ;-)
http://www.addedbytes.com/cheat-sheets/regular-expressions-cheat-sheet/
Good luck.

What is the best way to determine URL for local/staging/production?

For local testing the url is something like:
http://localhost:29234/default.aspx
For staging, the app is in a virtual directory:
http://stage/OurApp/default.aspx
For production, it's the root
http://www.ourcompany.com/default.aspx
However, sometimes we need to do a redirect to a particular directory. We don't always know exactly where we are at.
So, how would I do a redirect to say /subdir1/mypage.aspx?
MORE INFO
I neglected an important item. This url is sent back to the browser so that some javascript code can perform the redirect. (Odd, I know). So a regular ResolveUrl("~/pagename.aspx") won't give the full info...
UPDATE 2
I ended up with the following, which seems to work across the board... It looks a little ugly though.
StringBuilder buildUrl = new StringBuilder(#"http://");
buildUrl.Append(Request.Url.Host);
if (Request.Url.Port != 80) {
buildUrl.Append(":");
buildUrl.Append(Request.Url.Port.ToString());
}
buildUrl.Append(this.ResolveUrl("~/Pages/Customers.aspx"));
buildUrl.Append(String.Format("?AccountId={0}&tabName=Tab2&primaryCustomerId={1}", acctId, custId));
When paths start diverging between different environments, and you cannot bring any sanity to the situation, it's time to start puttin' paths in the web.config.
It's not a cure for inconsistent file paths, but it'll make your code consistent and you won't have to worry about having "let's figure out where i am" logic.
The tilde is a shortcut for HttpRuntime.AppDomainAppVirtualPath (more)
~/subdir1/mypage.aspx
If the subdir1 is a directory within your web application, you can use a relative link (subdir1/mypage.aspx instead of /subdir/mypage.aspx -- note the lack of the first forward slash). This way, it won't matter where your application is because the links will be relative to the current page.
A suggestion is you can use the BASE tag for the page which can be the root. by using this, all your relative paths will be resolved based on BASE path.
General Advice
I recommend storing the path in your settings. There are reasons why some of our projects need various paths and urls, and we can't always get away with using the tilde (~).
Our Strategy
In our projects here at Inntec, our web.config contains a database connection string and a variable saying what the environment is - Production, Staging, Development, etc.
Then, in the database, we've got a set of variables for each environment, and there's a nice class that strongly types the settings and pulls/caches the right setting for the current environment. So in our code we can say: Settings.AppUrl and everything just works.
We use Redgate's Sql Data Compare to sync the settings across all instances (so each environments always has the settings for all environments), and there are unit tests that make sure each environment has a complete batch of settings.
That's one way to do it... So far it has worked really well for us.

Can you rename the App_Code folder?

I realize this would violate convention, but I'm curious to know if you can do this through configuration.
Edit: I understand why I wouldn't want to do this. BUT, I do want to understand the internals of this time of project.
No you cannot rename this folder and have it actually contain executable code. The web project system is hard coded to look for code in this folder and will not consider any other folder for raw code.
Reflector tells me that System.Web.HttpRuntime contains...
internal const string CodeDirectoryName = "App_Code";
So the answer is no.
I dont think this is posible, but why do you need to change it?
Google "Convention over Configuration"

Resources