MVC bundles and IIS virtual directories (URL rewrite) - asp.net-mvc

I'm hosting multiple applications on IIS server virtual directories and I'm using URL Rewrite to facilitate them. All images and other assets that are manually written like this "~/path/to/my/content" has a correct output "/path/to/my/content", but bundle paths like "~/client/js" gives an output "/myapplication/client/js" which should be "/client/js".
How can I fix that?
How I initiate Script bundle:
var scriptBundle = new ScriptBundle("~/client/js");
Rewrite configuration:
<rule name="Official Website" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^(www\.)?domain\.com$" ignoreCase="true" negate="false" />
</conditions>
<action type="Rewrite" url="officialsite/{R:1}" />
</rule>
Was looking into these topics, but couldn't make anything work for me:
How do I get System.Web.Optimization bundles to work with custom folders in an IIS virtual directory?
CssRewriteUrlTransform with or without virtual directory
Why does ResolveBundleUrl not work for custom folders? (MVC Beta 4)
Is it possible to unit test BundleConfig in MVC4?
UPDATE: I'm using Winhost as hosting provider, and they do not support setting up host headers for the IP, probably due to the shared IP. They provide domain pointers to root folders, which is why I'm using URL rewrite.

You said :
I'm hosting multiple applications on IIS server virtual directories
and I'm using URL Rewrite to facilitate them
So, The problem refers to root configuration (Virtual Directory) to be usable for bundling and etc.., It's not about bundling configuration or rewrite rule. I think you need to setup myapplication directory as virtual and set it up as a separate website. Make sure you have followed instructions available in Create Web Site where it says:
you add a Web site in IIS, a site entry is created in the
ApplicationHost.config file. The entry specifies:
network binding for the site
Maps the site to a location in the file system
optionally specifies user credentials for content access
To ensure that user requests reach the correct Web site, you must configure a unique identity for each site on the server.Web sites hosted on the same server can be distinguished using the following unique identifiers.
Host header name (recommended)
IP address
TCP port number
Configure a Host Header for a Web Site (IIS 7) points to the first one.
Update: I think there may be a name conflict on server and your project. more brightly try to change client in ~/client/js and its folder to new one. Unless there were multiple path choices (with this path depth) for server to fetch that you can solve it by adding an extra depth by adding an \ in your project and js bundle mapping.
Update2: Finally I suggest you to follow full article available in How to publish or host subdomain on winhost.com? to solve such this amazing issue :)

I have two options you can try.
1) Try using this to trick it into using the correct path:
var scriptBundle = new ScriptBundle("~/../client/js");
You may get an HttpException (Cannot use a leading .. to exit above
the top directory.), but it's worth a shot. I cannot replicate your
environment, so I cannot test.
2) Create your own virtual path provider:
Changing ASP.net application root?

Related

Prevent direct access to files on IIS server

I have two servers, one for my mvc application and the other one as a storage for large files like images etc, both running on Windows Server 2012 R2.
How can I prevent direct access to the files on storage server?
say, mvc is on IP1/ and storage is on IP2/.
Link to a file would be like: IP2/MediaFiles/2015/12/image0001.jpg.
I need only GET requests from IP1 have access to the link above. How?
UPDATE
server1 on IP1 needs to be free of file sharing since media server is on IP2 and we don't need to load files per request on server1's RAM. (server1 will crash soon!) therefore no HttpHandler can be used!
In this question I'm looking for a way to prevent unauthorized users from accessing files on server2 (on IP2) by entering direct address.
Alright I found the solution!
Working on such problems needs some trick gathered from different sources based on your needs. I was looking for a way to prevent unauthorized users from accessing files on file server which is different from your main server. (the main server is authorizing users)
First of all, I blocked ALL incoming requests containing the Url pattern of my sensitive files using IIS rules. Then I wrote some lines of code for file server to handle Http requests using IHttpHandler interface in order to 1) check authorization rules and 2) send exact files to clients without converting them to byte array. And lastly, I used This Link to prettify links to file server! That's all folks ;)
Now:
physical link [blocked] : IP2/MediaFiles/2015/12/image0001.jpg
virtual link : IP2/Please/Find/A/File/By/DB/Id/1 ---> image0001.jpg
All what you wanted is in Web.Config file. You should place it in the root directory of your file storage server if you using IIS there.
In <system.webServer> node you should place this code:
<security>
<ipSecurity allowUnlisted="false"> <!-- this line blocks everybody, except those listed below -->
<clear/> <!-- removes all upstream restrictions -->
<add ipAddress="127.0.0.1" allowed="true"/> <!-- allow requests from the local machine -->
<add ipAddress="IP1" allowed="true"/> <!-- allow the specific IP of IP1 -->
</ipSecurity>
</security>
This rule will be accepted for all subfolders of root folder. If you need to block requests only for specific folder you should place your Web.Config there.

Protocol Binding error with wildcard sub domains in Windows Azure websites

I have multi tenant MVC application running as an Azure website. Tenants are resolved by using sub domains. So tenant A can be resolved by http://tenanta.myapp.com. This works perfectly well as long as I go and create individual CNAME records on my DNS server for each tenant. However I do not want to have to do this.
So I successfully added a wildcard A record *.myapp.com to my DNS records and in azure I added a custom domain name *.MyApp.com. So now I can use http://anything.myapp.com and it will resolved to my azure website ok. So that was great and I thought I was up and running.
Until I tried to browse to a page that is using AJAX to call a WCF service (the WCF service is internal to the website). There are a bunch of WCF services and they all throw a 500.
System.UriFormatException: The protocol binding '*:80:*.myapp.com' is not valid for 'http'. This might be because the port number is out of range.
If I remove the *.myapp.com from the list of custom domains in Azure then I don't get the error but my wildcard subdomains no longer get directed to the website and I get a 404 from azure.
I've tried a few things with the bindings for the WCF services including trying all of the HostNameComparisonMode options StrongWildcard, WeakWildcard and Exact.
I was hoping someone else had come accross this problem before. There are bunch of posts on getting the wildcard subdomains working but nothing specific to the issue I am having with WCF services.
Thanks in advance
This might be due to a binding of the shape :80:.myapp.com gets created in the applicaitonHost.config when the wildcard custom domain name is added to the site (in Azure Web Sites service). We will investigate and try to get this fixed.
Meanwhile, it might be worth a try to clear the bindings section in your web.config and recreate a binding of the form
<binding protocol="http" bindinginformation="*:80:"/>
Let me know if this works.
To add on Zhe's answer here is how it can be done:
Create an applicationHost.xdt file under your 'site' folder, and copy the content below into it
(more info on transform on Kudu site)
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.applicationHost>
<sites>
<site name="%XDT_SITENAME%" xdt:Locator="Match(name)">
<bindings>
<binding protocol="http" bindingInformation="'*:80:*.myapp.com" xdt:Locator="Match(bindingInformation)" xdt:Transform="Remove" />
</bindings>
</site>
</sites>
</system.applicationHost>
</configuration>
In azure, for custom domain name, add * instead of *.myapp.com and that should work.

MVC Publish to host is adding extra sub folders

I'm publishing an MVC 3 site to a go daddy account. I'm using the FTP Publish utility in VS 2010. The site publishes "okay". But here is the issue:
On my local machine, when I run it the web address is:
localhost/Student/Create
On my go daddy account, I have created a subdirectory called mvctest.
I have created a subdomain called mvctest.mysite.com that points to the virtual directory at mvctest. This works fine.
But after I publish my site to www.mysite.com/mvctest, I am getting an additional /mvctest/ directory in all of my links. What I want is:
mvctest.mysite.com/Student/Create
what I get is:
mvctest.mysite.com/mvctest/Student/Create
What's interesting is that if I manually type in what I want, the page loads fine. If I've hard-coded a link to the root, it's fine, but all of my Url.Content and Html. Links add the additional mvctest directory..
I've searched all over and haven't found an answer to this dilemma. I tried in the web.config, but I don't think that does it. I feel like something in the FTP Publish utility in VS2010 is altering the routing structure in my global.asax file, but I'm not sure.
Any suggestions appreciated.
Is your virtual directory an application? If it's not set as an application, IIS will treat the root of your site as the application and add the subdirectory. See this post.
The following solved the same issue for me and is quoted from a blog post I found (source):
So now for the solution, and I probably should have mentioned this at the beginning but hopefully you’re using IIS7 with the URL rewriting module installed (it is installed by default when you use IIS7 on GoDaddy).
Simply add the following into your web.config’s system.webServer element:
<rewrite>
<rules>
<rule name="Remove Virtual Directory">
<match url=".*" />
<action type="Rewrite" url="{R:0}" />
</rule>
</rules>
</rewrite>
All this does is “rewrite” the URL with itself. This causes URL Rewrite to add the original URL (the one with no folder name) to a ServerVariable which is used by ASP.NET MVC to generate other URLs.

Does Umbraco allow non-umbraco subdomains

Hi I am installing Umbraco to the root directory of my website. And also I want to install my wordpress blog to a subfolder in the root directory.
However any request to the subfolder is being intercepted by Umbraco and it is showing that document URL cannot be found. Is there a way to make Umbraco ignore certain subdomains?
You can tell Umbraco to ignore certain paths or folders in the web.config.
You need to update the following entry in the appSetting section of the web.config:
umbracoReservedPaths
Add the subfolder you wish Umbraco to ignore in there.
i.e.
<add key="umbracoReservedPaths" value="/umbraco,/install/,/wordpress/" />
There are more details on the Umbraco web.config settings in on our.umbraco.org
it's useful for binding too:
<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/http-bind/" />
~/http-bind/
Thanks Tim Saunders
You can also use umbracoReservedUrls to tell umbraco to ignore specific pages:
<add key="umbracoReservedUrls" value="/mypages/regular-page.aspx" />
This can be set up with in IIS by setting up the blog as a separate application with in the umbraco site.
However if you are trying to make a sub-domain there is no reason why this should be in the same site, I would say it is best to create a separate site with in IIS or purchase another hosting account to host the blog separately

How to host an asp.net mvc app on a domain that points to a subfolder?

I have the folowing scenario:
www.somedomain.com -> this points to a folder on a shared host, say /MyFolder1
www.otherdomain.com -> this points to another folder on the same shared host, say /MyFolder2
With asp.net mvc my urls get mapped to:
www.somedomain.com/MyFolder1/Action
www.somedomain.com/MyFolder2/Action
I (obviosly) dont't want to have "MyFolder1" and "MyFolder2" on my URLs. How do i solve this on asp.net MVC?
I want to have:
www.somedomain.com/Action
www.somedomain.com/Action
But i need to keep the subfolders on IIS (or some other solution that allows me to have two sites, with different domains on the same hosting).
Help is very much appreciated.
Thanks
The best way to handle this IMO is to use rewriting at the IIS level. I just did this on a site using IIS 7 URL Rewrite. If you don't have this module installed on your host provider, you can try to use one of the other URL rewriting tools. But, for example on DiscountASP you can use IIS 7 URL rewrite.
First you need to point all your domains to your current site. Then when you download the tool: http://blogs.iis.net/bills/archive/2008/05/31/urlrewrite-module-for-iis7.aspx, it provides a GUI for editing the rules. Ultimately the rules are placed into your web.config file. You want your rules to look something like this:
<rewrite>
<rewriteMaps>
<rewriteMap name="otherdomain" />
</rewriteMaps>
<rules>
<rule name="otherdomain" stopProcessing="false">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="otherdomain.com" />
</conditions>
<action type="Rewrite" url="/site_folder/otherdomain/{R:0}" />
</rule>
</rules>
</rewrite>
If you are using ISAPI rewrite, I'll probably have that one soon as well for another host that I'm using that doesn't support IIS rewrite
My hosting provider is using IIS 6 with ISAPI_Rewrite.
It works fine, www.somedomain.com/MyFolder1/Action becomes www.somedomain.com/Action as i want on the entry page. But all Url.ActionLink() maps again to www.somedomain.com/MyFolder1/Action which i don't want.
The easiest thing to do would be to create a subdomain on the shared host. Something like app1.somedomain.com and app2.somedomain.com, the subdomain maps directly to the subdirectory where the application is and that becomes the root.

Resources