What's the best method in ASP.NET to obtain the current domain? - asp.net

I am wondering what the best way to obtain the current domain is in ASP.NET?
For instance:
http://www.domainname.com/subdir/ should yield http://www.domainname.com
http://www.sub.domainname.com/subdir/ should yield http://sub.domainname.com
As a guide, I should be able to add a url like "/Folder/Content/filename.html" (say as generated by Url.RouteUrl() in ASP.NET MVC) straight onto the URL and it should work.

Same answer as MattMitchell's but with some modification.
This checks for the default port instead.
Edit: Updated syntax and using Request.Url.Authority as suggested
$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"

As per this link a good starting point is:
Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host
However, if the domain is http://www.domainname.com:500 this will fail.
Something like the following is tempting to resolve this:
int defaultPort = Request.IsSecureConnection ? 443 : 80;
Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host
+ (Request.Url.Port != defaultPort ? ":" + Request.Url.Port : "");
However, port 80 and 443 will depend on configuration.
As such, you should use IsDefaultPort as in the Accepted Answer above from Carlos Muñoz.

Request.Url.GetLeftPart(UriPartial.Authority)
This is included scheme.

WARNING! To anyone who uses Current.Request.Url.Host. Understand that you are working based on the CURRENT REQUEST and that the current request will not ALWAYS be with your server and can sometimes be with other servers.
So if you use this in something like, Application_BeginRequest() in Global.asax, then 99.9% of the time it will be fine, but 0.1% you might get something other than your own server's host name.
A good example of this is something I discovered not long ago. My server tends to hit http://proxyjudge1.proxyfire.net/fastenv from time to time. Application_BeginRequest() gladly handles this request so if you call Request.Url.Host when it's making this request you'll get back proxyjudge1.proxyfire.net. Some of you might be thinking "no duh" but worth noting because it was a very hard bug to notice since it only happened 0.1% of the time : P
This bug has forced me to insert my domain host as a string in the config files.

Why not use
Request.Url.Authority
It returns the whole domain AND the port.
You still need to figure http or https

Simple and short way (it support schema, domain and port):
Use Request.GetFullDomain()
// Add this class to your project
public static class HttpRequestExtensions{
public static string GetFullDomain(this HttpRequestBase request)
{
var uri= request?.UrlReferrer;
if (uri== null)
return string.Empty;
return uri.Scheme + Uri.SchemeDelimiter + uri.Authority;
}
}
// Now Use it like this:
Request.GetFullDomain();
// Example output: https://example.com:5031
// Example output: http://example.com:5031

Another way:
string domain;
Uri url = HttpContext.Current.Request.Url;
domain= url.AbsoluteUri.Replace(url.PathAndQuery, string.Empty);

How about:
NameValueCollection vars = HttpContext.Current.Request.ServerVariables;
string protocol = vars["SERVER_PORT_SECURE"] == "1" ? "https://" : "http://";
string domain = vars["SERVER_NAME"];
string port = vars["SERVER_PORT"];

In Asp.Net Core 3.1 if you want to get a full domain, here is what you need to do:
Step 1: Define variable
private readonly IHttpContextAccessor _contextAccessor;
Step 2: DI into the constructor
public SomeClass(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
Step 3: Add this method in your class:
private string GenerateFullDomain()
{
string domain = _contextAccessor.HttpContext.Request.Host.Value;
string scheme = _contextAccessor.HttpContext.Request.Scheme;
string delimiter = System.Uri.SchemeDelimiter;
string fullDomainToUse = scheme + delimiter + domain;
return fullDomainToUse;
}
//Examples of usage GenerateFullDomain() method:
//https://example.com:5031
//http://example.com:5031

Using UriBuilder:
var relativePath = ""; // or whatever-path-you-want
var uriBuilder = new UriBuilder
{
Host = Request.Url.Host,
Path = relativePath,
Scheme = Request.Url.Scheme
};
if (!Request.Url.IsDefaultPort)
uriBuilder.Port = Request.Url.Port;
var fullPathToUse = uriBuilder.ToString();

How about:
String domain = "http://" + Request.Url.Host

Related

Different ways to set url path in base tag in mvc website

Hi i am just passing url like this in my MVC website:
<base href="http:4546//localhost/" />
It works in local but if i am hosting it on ISS.This url creates issues.
If i am removing 4546 in url like this:
http://localhost/Home/Contact
Then its working.
I tried it by removing port number in code but still in url port number displays itself.
how i can remove port number or what will be the way so i can host it with port number 80 on public?
Please let me know where i am lacking.
Thanks
You can create one Base Controller and add this method
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var request = HttpContext.Request;
var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, HttpRuntime.AppDomainAppVirtualPath == "/" ? "" : HttpRuntime.AppDomainAppVirtualPath);
ViewBag.BasePath = baseUrl;
}
This method OnActionExecuting will always be called on each request and user this viewbag in you code.
This will resolve your issue of writting every where in code.
I was running into a similar issue where, on certain IIS configurations, the base tag (which is necessary for AngularJS) was providing the incorrect address. The way I got around this is by replacing <base href="/"> with:
<base href="#(string.Format("{0}://{1}{2}/", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority, HttpRuntime.AppDomainAppVirtualPath == "/" ? "" : HttpRuntime.AppDomainAppVirtualPath))">
This is basically a shorter version of Sulay's solution, but it has worked for me so far.
My need to set base tag stems from using AngularJS as it requires base for correct routing, if html5 mode is on.
I ended up with this method:
private const string Action = "action";
private const string Controller = "controller";
public static string CurrentActionWithoutRouteReuse(this UrlHelper urlHelper)
{
var routeValues = urlHelper.RequestContext.RouteData.Values;
var actionName = (string)routeValues[Action];
var controllerName = (string)routeValues[Controller];
var routeValuesWithoutParams = new RouteValueDictionary(routeValues);
routeValuesWithoutParams.Remove(Action);
routeValuesWithoutParams.Remove(Controller);
routeValuesWithoutParams.Keys
.ToList().ForEach(parameterName => routeValuesWithoutParams[parameterName] = null);
var url = urlHelper.Action(actionName, controllerName, routeValuesWithoutParams);
return url.EndsWith("/") ? url : url + "/";
}
Note, here I explicitly set other params to null. That is because of route reuse which MVC uses, but I didn't need at the moment.
Why not just adding this in your page?
<base href="~/">
This will be replaced when compiled by your URL path. I do that to make routing work for my Angular (2+) app and it works fine.

Url helper for full url in asp.net mvc-3

Writing
#Url.Content("~/Something/Something.html")
in razor renders
/AppFolder/Something/Something.html
Is there a way to render the full URL like http://www.something.com/AppFolder/Something/Something.html without atrocious hacks? (like storing the protocol and domain in the AppConfig, and concatenate the string to it)
Is there a helper like #Url.FullPath("~/asdf/asdf") or similar?
See this blog post for the answer.
Basically, all you need to do it include the protocol parameter e.g.
Url.Action("About", "Home", null, "http")
The #Url.RouteURL() does not quiet answer this question. It does work for named routes but falls short for arbitrary virtual paths.
Here is quick helper method that generates full outbound url. You can create overloads for various schemes (http[s]) depending on the degree of control desired.
public static class UrlHelperExtension
{
public static string ContentFullPath(this UrlHelper url,string virtualPath)
{
var result = string.Empty;
Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
result = string.Format("{0}://{1}{2}",
requestUrl.Scheme,
requestUrl.Authority,
VirtualPathUtility.ToAbsolute(virtualPath));
return result;
}
}
For anyone needing to build URLs in WebAPI 2.2 and/or MVC5, this worked for me:
// works in a controller
var requestUri = this.Request.RequestUri;
// just the http/s and the hostname; ymmv
string baseUrl = requestUri.Scheme + "://" + requestUri.Authority + "/";
// build your url for whatever purpose you need it for
string url = baseUrl + "SomeOtherController?id=" + <some_magic_value>;
You can use a helper to produce a full url, including protocol. Note the first lowercase in url.Action.
var url = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext);
var fullUrl = url.Action("YourAction", "YourController", new { id = something }, protocol: System.Web.HttpContext.Current.Request.Url.Scheme);
Output
https://www.yourdomain.com/YourController/YourAction?id=something

Asp.net 4 url rewrite a subdomain as a folder

What I'm trying to do is the following, I want to rewrite this kind of url:
blog.domain.com/...
into
domain.com/blog/...
It's in a shared host environment, using IIS7/ASP.Net 4. Another thing is that both the domain and the blog subdomain have different aps running. I've been searching for hours for what's the best solution here, and I hope someone can guide me a bit here. Thanks!
Here is an attempt as first idea.
// keep a valid list somewhere
List<string> cValidNames = new List<string>();
cValidNames.Add("blog");
// get the host
//string TheHost = Request.Url.Host;
string TheHost = "blog.domain.com";
// find the first part, assume that the domain is standard and not change
int WhereStarts = TheHost.IndexOf(".domain.com");
// if we found it
if(WhereStarts != -1)
{
string cTheFirstPart = TheHost.Substring(0, WhereStarts);
// if its on the valid domain (exclude the www)
if (cValidNames.Contains(cTheFirstPart))
{
// now I add in the frond the name and continue with the rest url
string cFinalPath = "/" + cTheFirstPart + Request.RawUrl;
// now rewrite it.
HttpContext.Current.RewritePath(cFinalPath, false);
return;
}
}

Find application root URL without using ~

I need to construct the URL of a page in a String, to send it an email (as part of an email verification system). If i use the ~ symbol to denote the app root, it is taken literally.
The app will be deployed on a server on three different sites (on different ports) and each site can be accessed via 2 different URLs (one for LAn and one for internet).
So hardcoding the URL is out of question. I want to construct the url to verify.aspx in my application
Please help
You need this:
HttpContext.Current.Request.ApplicationPath
It's equivalent to "~" in a URL.
http://msdn.microsoft.com/en-us/library/system.web.httprequest.applicationpath.aspx
Unfortunately none of the methods listed generated the full url starting from http://---.
So i had to extract these from request.url. Something like this
Uri url=HttpContext.Current.Request.Url;
StringBuilder urlString = new StringBuilder();
urlString.Append(url.Scheme);
urlString.Append("://");
urlString.Append(url.Authority);
urlString.Append("/MyDesiredPath");
Can someone spot any potential problems with this?
Try:
HttpRequest req = HttpContext.Current.Request;
string url = req.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped)
+ ((req.ApplicationPath.Length > 1) ? req.ApplicationPath : "");
You need to put the URL as part of your web application's configuration. The web application does not know how it can be reached from the outside world.
E.g. consider a scenario where there's multiple proxies and load balancers in front of your web server... how would the web server know anything but its own IP?
So, you need to configure each instance of your web application by adding the base URL e.g. as an app setting in its web.config.
You can use HttpRequest.RawURL (docs here)property and base your URL on that, but if you are behind any kind of redirection, the RawURL may not reflect the actual URL of your application.
I ended up with this. I take the request url, and use the position of Request.ApplicationRoot to discover the left part of the uri. Should work with applications hosted in a virtual directory "/example" or in the root "/".
private string GetFullUrl(string relativeUrl)
{
if (string.IsNullOrWhiteSpace(relativeUrl))
throw new ArgumentNullException("relativeUrl");
if (!relativeUrl.StartsWith("/"))
throw new ArgumentException("url should start with /", "relativeUrl");
string current = Request.Url.ToString();
string applicationPath = Request.ApplicationPath;
int applicationPathIndex = current.IndexOf(applicationPath, 10, StringComparison.InvariantCultureIgnoreCase);
// should not be possible
if (applicationPathIndex == -1) throw new InvalidOperationException("Unable to derive root path");
string basePath = current.Substring(0, applicationPathIndex);
string fullRoot = string.Concat(
basePath,
(applicationPath == "/") ? string.Empty : applicationPath,
relativeUrl);
return fullRoot;
}
This has always worked for me:
string root = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, "");

How do I convert a file path to a URL in ASP.NET

Basically I have some code to check a specific directory to see if an image is there and if so I want to assign a URL to the image to an ImageControl.
if (System.IO.Directory.Exists(photosLocation))
{
string[] files = System.IO.Directory.GetFiles(photosLocation, "*.jpg");
if (files.Length > 0)
{
// TODO: return the url of the first file found;
}
}
this is what i use:
private string MapURL(string path)
{
string appPath = Server.MapPath("/").ToLower();
return string.Format("/{0}", path.ToLower().Replace(appPath, "").Replace(#"\", "/"));
}
As far as I know, there's no method to do what you want; at least not directly. I'd store the photosLocation as a path relative to the application; for example: "~/Images/". This way, you could use MapPath to get the physical location, and ResolveUrl to get the URL (with a bit of help from System.IO.Path):
string photosLocationPath = HttpContext.Current.Server.MapPath(photosLocation);
if (Directory.Exists(photosLocationPath))
{
string[] files = Directory.GetFiles(photosLocationPath, "*.jpg");
if (files.Length > 0)
{
string filenameRelative = photosLocation + Path.GetFilename(files[0])
return Page.ResolveUrl(filenameRelative);
}
}
The problem with all these answers is that they do not take virtual directories into account.
Consider:
Site named "tempuri.com/" rooted at c:\domains\site
virtual directory "~/files" at c:\data\files
virtual directory "~/files/vip" at c:\data\VIPcust\files
So:
Server.MapPath("~/files/vip/readme.txt")
= "c:\data\VIPcust\files\readme.txt"
But there is no way to do this:
MagicResolve("c:\data\VIPcust\files\readme.txt")
= "http://tempuri.com/files/vip/readme.txt"
because there is no way to get a complete list of virtual directories.
I've accepted Fredriks answer as it appears to solve the problem with the least amount of effort however the Request object doesn't appear to conatin the ResolveUrl method.
This can be accessed through the Page object or an Image control object:
myImage.ImageUrl = Page.ResolveUrl(photoURL);
myImage.ImageUrl = myImage.ResolveUrl(photoURL);
An alternative, if you are using a static class as I am, is to use the VirtualPathUtility:
myImage.ImageUrl = VirtualPathUtility.ToAbsolute(photoURL);
This worked for me:
HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + HttpRuntime.AppDomainAppVirtualPath + "ImageName";
Maybe this is not the best way, but it works.
// Here is your path
String p = photosLocation + "whatever.jpg";
// Here is the page address
String pa = Page.Request.Url.AbsoluteUri;
// Take the page name
String pn = Page.Request.Url.LocalPath;
// Here is the server address
String sa = pa.Replace(pn, "");
// Take the physical location of the page
String pl = Page.Request.PhysicalPath;
// Replace the backslash with slash in your path
pl = pl.Replace("\\", "/");
p = p.Replace("\\", "/");
// Root path
String rp = pl.Replace(pn, "");
// Take out same path
String final = p.Replace(rp, "");
// So your picture's address is
String path = sa + final;
Edit: Ok, somebody marked as not helpful. Some explanation: take the physical path of the current page, split it into two parts: server and directory (like c:\inetpub\whatever.com\whatever) and page name (like /Whatever.aspx). The image's physical path should contain the server's path, so "substract" them, leaving only the image's path relative to the server's (like: \design\picture.jpg). Replace the backslashes with slashes and append it to the server's url.
So far as I know there's no single function which does this (maybe you were looking for the inverse of MapPath?). I'd love to know if such a function exists. Until then, I would just take the filename(s) returned by GetFiles, remove the path, and prepend the URL root. This can be done generically.
The simple solution seems to be to have a temporary location within the website that you can access easily with URL and then you can move files to the physical location when you need to save them.
For get the left part of the URL:
?HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority)
"http://localhost:1714"
For get the application (web) name:
?HttpRuntime.AppDomainAppVirtualPath
"/"
With this, you are available to add your relative path after that obtaining the complete URL.
I think this should work. It might be off on the slashes. Not sure if they are needed or not.
string url = Request.ApplicationPath + "/" + photosLocation + "/" + files[0];

Resources