YSLOW Expiry Headers on MVC 5 Web Site - asp.net-mvc

I used YSlow to test an ASP.NET MVC web site and I got the error:
"Add Expiry Headers" for the following items:
(no expires) http://www.mydomain.pt/assets/logo.png
(no expires) http://www.mydomain.pt/favicon-196x196.png
(2013/12/30) http://www.mydomain.pt/file/e6fb9d2a-668b-423a-9120-0b34228f296c
What is strange is that I addressed these issues. For static I used:
CORRECTED
<system.webServer>
<clientCache setEtag="false" cacheControlMode="UseMaxAge" cacheControlMaxAge="60.00:00:00" />
</system.webServer>
And for the file, returned by an action, I have:
[Route("file/{identifier:guid}"), HttpGet, OutputCache(Duration = 1200, Location = OutputCacheLocation.Client, VaryByParam = "identifier")]
public virtual ActionResult Get(Guid identifier, String n = null) {
}
Does anyone knows why I still have no cache on these items?
Am I missing something?
Thank You,
Miguel

Use following syntax:
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="60.00:00:00" />
</staticContent>
</system.webserver>

Compressing static files doesn't have anything to do with expiration headers. Compression is related to GZip.
The reason the .png files do not have the Expiry header that you are setting in the action method, is that MVC is not being used to serve the static files, so it will not set the headers.
Add expires header to images

Related

HTTP 413 - Request Entity Too Large cheat sheet

I am trying to upload a large file to my ASP.net core/ASP.net mvc site, but keep on encountering HTTP 413 - request entity too large. Even when I try to update web.config, other things still break.
Does anyone have a cheat sheet for dealing with this?
I created an asp.net mvc application and tried to test it.
Often we only pay attention to the uploadReadAheadSize setting, but tests have proved that this cannot completely solve the problem, and there are other configurations that need to be configured. (Added based on Jack's answer)
In addition to setting the uploadReadAheadSize value larger, there are also maxAllowedContentLength and maxRequestLength. You need to modify all these three values, otherwise the 413 or Maximum request length exceeded error will still be displayed.
In my test results, the application can upload any type of file within 1GB.
This works for me. Set it in your web.config under the configuration section:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="999999999" />
</requestFiltering>
</security>
</system.webServer>
Here is my cheat sheet:
The max file size limit coming through from IIS is specified through the UploadReadAhaead parameter, which can be specified in web.config as so. In this case, the maximum is set to 1000485760 bytes
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Detailed"></httpErrors>
<serverRuntime uploadReadAheadSize="1000485760" />
<httpErrors errorMode="Detailed" />
<asp scriptErrorSentToBrowser="true"/>
</system.webServer>
<system.web>
<customErrors mode="Off"/>
<compilation debug="true"/>
</system.web>
</configuration>
This is grand, as long as this specifier actually works. You might need a different solution, say, if you are hosting locally with something other than IIS (like kestrel, or even IIS express.)
Sometimes this configuration section is locked as well, in which case it can be unlocked using the following command (run cmd as admin):
%windir%\system32\inetsrv\appcmd.exe unlock config -section:system.webServer/serverRuntime
This is also something to consider when setting up prod. In some cases, your configuration within web.config within your code for the uploadReadAheadSize can conflict with whatever is specified in your prod instance. For me, I ended up getting rid of my configuration within source control, and instead, set the uploadReadAhead value for prod during environment set up. I did this by running the command (in cmd as admin):
appcmd set config "https://example.com" /section:system.webserver/serverruntime /uploadreadaheadsize:500048576 /commit:apphost
appcmd set config "http://example.com" /section:system.webserver/serverruntime /uploadreadaheadsize:500048576 /commit:apphost
I also set uploadReadAheadSize within C:\inetpub\wwwroot\web.config on the prod server as well, so it looks something like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<serverRuntime uploadReadAheadSize="500485760" />
<!--If this line breaks, unlock the config by opening cmd as admin and running %windir%\system32\inetsrv\appcmd.exe unlock config -section:system.webServer/serverRuntime-->
</system.webServer>
</configuration>
This can also be set as per this screenshot:
[![enter image description here][1]][1]
Now that you've set this up, it's still entirely possible that your application breaks, giving you a 413 because even though IIS may be set up correctly, there are also upload limits within the .net core ecosystem which can throw an HTTP 414 error when handling large files. This is something I found out [here][2]
The TLDR of this is that you want to have the following code within your startup.cs -> configureServices()
services.Configure<IISServerOptions>(options => {
options.MaxRequestBodySize = int.MaxValue;
});
services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = int.MaxValue;
x.BufferBodyLengthLimit = int.MaxValue;
x.MultipartBoundaryLengthLimit = int.MaxValue;
});
Note that there is code in there for if you are hosting for kestrel rather than IIS, also
[1]: https://i.stack.imgur.com/yLHQQ.png
[2]: https://github.com/dotnet/aspnetcore/issues/20369#issuecomment-607057822

HTTP Error 404.0 - Not Found on action in controller. MVC [duplicate]

I have a project that requires my URLs have dots in the path. For example I may have a URL such as www.example.com/people/michael.phelps
URLs with the dot generate a 404. My routing is fine. If I pass in michaelphelps, without the dot, then everything works. If I add the dot I get a 404 error. The sample site is running on Windows 7 with IIS8 Express. URLScan is not running.
I tried adding the following to my web.config:
<security>
<requestFiltering allowDoubleEscaping="true"/>
</security>
Unfortunately that didn't make a difference. I just receive a 404.0 Not Found error.
This is a MVC4 project but I don't think that's relevant. My routing works fine and the parameters I expect are there, until they include a dot.
What do I need to configure so I can have dots in my URL?
I got this working by editing my site's HTTP handlers. For my needs this works well and resolves my issue.
I simply added a new HTTP handler that looks for specific path criteria. If the request matches it is correctly sent to .NET for processing. I'm much happier with this solution that the URLRewrite hack or enabling RAMMFAR.
For example to have .NET process the URL www.example.com/people/michael.phelps add the following line to your site's web.config within the system.webServer / handlers element:
<add name="ApiURIs-ISAPI-Integrated-4.0"
path="/people/*"
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
Edit
There are other posts suggesting that the solution to this issue is RAMMFAR or RunAllManagedModulesForAllRequests. Enabling this option will enable all managed modules for all requests. That means static files such as images, PDFs and everything else will be processed by .NET when they don't need to be. This options is best left off unless you have a specific case for it.
After some poking around I found that relaxedUrlToFileSystemMapping did not work at all for me, what worked in my case was setting RAMMFAR to true, the same is valid for (.net 4.0 + mvc3) and (.net 4.5 + mvc4).
<system.webserver>
<modules runAllManagedModulesForAllRequests="true">
Be aware when setting RAMMFAR true Hanselman post about RAMMFAR and performance
I believe you have to set the property relaxedUrlToFileSystemMapping in your web.config. Haack wrote an article about this a little while ago (and there are some other SO posts asking the same types of question)
<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
Edit
From the comments below, later versions of .NET / IIS may require this to be in the system.WebServer element.
<system.webServer>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
I got stuck on this issue for a long time following all the different remedies without avail.
I noticed that when adding a forward slash [/] to the end of the URL containing the dots [.], it did not throw a 404 error and it actually worked.
I finally solved the issue using a URL rewriter like IIS URL Rewrite to watch for a particular pattern and append the training slash.
My URL looks like this: /Contact/~firstname.lastname so my pattern is simply: /Contact/~(.*[^/])$
I got this idea from Scott Forsyth, see link below:
http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path
Just add this section to Web.config, and all requests to the route/{*pathInfo} will be handled by the specified handler, even when there are dots in pathInfo. (taken from ServiceStack MVC Host Web.config example and this answer https://stackoverflow.com/a/12151501/801189)
This should work for both IIS 6 & 7. You could assign specific handlers to different paths after the 'route' by modifying path="*" in 'add' elements
<location path="route">
<system.web>
<httpHandlers>
<add path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" />
</httpHandlers>
</system.web>
<!-- Required for IIS 7.0 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</location>
MVC 5.0 Workaround.
Many of the suggested answers doesn't seem to work in MVC 5.0.
As the 404 dot problem in the last section can be solved by closing that section with a trailing slash, here's the little trick I use, clean and simple.
While keeping a convenient placeholder in your view:
#Html.ActionLink("Change your Town", "Manage", "GeoData", new { id = User.Identity.Name }, null)
add a little jquery/javascript to get the job done:
<script>
$('a:contains("Change your Town")').on("click", function (event) {
event.preventDefault();
window.location.href = '#Url.Action("Manage", "GeoData", new { id = User.Identity.Name })' + "/";
});</script>
please note the trailing slash, that is responsible for changing
http://localhost:51003/GeoData/Manage/user#foo.com
into
http://localhost:51003/GeoData/Manage/user#foo.com/
Super easy answer for those that only have this on one webpage. Edit your actionlink and a + "/" on the end of it.
#Html.ActionLink("Edit", "Edit", new { id = item.name + "/" }) |
Depending on how important it is for you to keep your URI without querystrings, you can also just pass the value with dots as part of the querystring, not the URI.
E.g. www.example.com/people?name=michael.phelps will work, without having to change any settings or anything.
You lose the elegance of having a clean URI, but this solution does not require changing or adding any settings or handlers.
You might want to think about using dashes instead of periods.
In Pro ASP MVC 3 Framework they suggest this about making friendly URLs:
Avoid symbols, codes, and character sequences. If you want a word
separator, use a dash (/my-great-article). Underscores are unfriendly,
and URL-encoded spaces are bizarre (/my+great+article) or disgusting
(/my%20great%20article).
It also mentions that URLs should be be easy to read and change for humans. Maybe a reason to think about using a dash instead of a dot also comes from the same book:
Don't use file name extensions for HTML pages (.aspx or .mvc), but do use them for specialized file types (.jpg, .pdf, .zip, etc). Web browsers don't care about file name extensions if you set the MIME type appropriately, but humans still expect PDF files to end with .pdf
So while a period is still readable to humans (though less readable than dashes, IMO), it might still be a bit confusing/misleading depending on what comes after the period. What if someone has a last name of zip? Then the URL will be /John.zip instead of /John-zip, something that can be misleading even to the developer that wrote the application.
Would it be possible to change your URL structure?
For what I was working on I tried a route for
url: "Download/{fileName}"
but it failed with anything that had a . in it.
I switched the route to
routes.MapRoute(
name: "Download",
url: "{fileName}/Download",
defaults: new { controller = "Home", action = "Download", }
);
Now I can put in localhost:xxxxx/File1.doc/Download and it works fine.
My helpers in the view also picked up on it
#Html.ActionLink("click here", "Download", new { fileName = "File1.doc"})
that makes a link to the localhost:xxxxx/File1.doc/Download format as well.
Maybe you could put an unneeded word like "/view" or action on the end of your route so your property can end with a trailing / something like /mike.smith/view
As solution could be also considering encoding to a format which doesn't contain symbol., as base64.
In js should be added
btoa(parameter);
In controller
byte[] bytes = Convert.FromBase64String(parameter);
string parameter= Encoding.UTF8.GetString(bytes);
It's as simple as changing path="." to path="". Just remove the dot in the path for ExensionlessUrlHandler-Integrated-4.0 in web.config.
Here's a nice article https://weblog.west-wind.com/posts/2015/Nov/13/Serving-URLs-with-File-Extensions-in-an-ASPNET-MVC-Application
Tried all the solutions above but none of them worked for me. What did work was I uninstalling .NET versions > 4.5, including all its multilingual versions; Eventually I added newer (English only) versions piece by piece. Right now versions installed on my system is this:
2.0
3.0
3.5 4
4.5
4.5.1
4.5.2
4.6
4.6.1
And its still working at this point. I'm afraid to install 4.6.2 because it might mess everything up.
So I could only speculate that either 4.6.2 or all those non-English versions were messing up my configuration.
I was able to solve my particular version of this problem (had to make /customer.html route to /customer, trailing slashes not allowed) using the solution at https://stackoverflow.com/a/13082446/1454265, and substituting path="*.html".
Add URL Rewrite rule to Web.config archive. You need to have the URL Rewrite module already installed in IIS. Use the following rewrite rule as inspiration for your own.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Add trailing slash for some URLs" stopProcessing="true">
<match url="^(.*(\.).+[^\/])$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Redirect" url="{R:1}/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Also, (related) check the order of your handler mappings. We had a .ashx with a .svc (e.g. /foo.asmx/bar.svc/path) in the path after it. The .svc mapping was first so 404 for the .svc path which matched before the .asmx.
Havn't thought too much but maybe url encodeing the path would take care of this.
This is the best solution I have found for the error 404 on IIS 7.5 and .NET Framework 4.5 environment, and without using: runAllManagedModulesForAllRequests="true".
I followed this thread: https://forums.asp.net/t/2070064.aspx?Web+API+2+URL+routing+404+error+on+IIS+7+5+IIS+Express+works+fine and I have modified my web.config accordingly, and now the MVC web app works well on IIS 7.5 and .NET Framework 4.5 environment.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
[RoutePrefix("File")]
[Route("{action=index}")]
public class FileController : Controller
{
// GET: File
public ActionResult Index()
{
return View();
}
[AllowAnonymous]
[Route("Image/{extension?}/{filename}")]
public ActionResult Image(string extension, string filename)
{
var dir = Server.MapPath("/app_data/images");
var path = Path.Combine(dir, filename+"."+ (extension!=null? extension:"jpg"));
// var extension = filename.Substring(0,filename.LastIndexOf("."));
return base.File(path, "image/jpeg");
}
}
}

How do I change the content type of static script files in ASP.NET MVC?

I have a standard ASP.NET MVC 5 web project, but I would like all the .js files within the Script folder to be served to the browser with the content type set to text/ecmascript instead of application/javascript.
The problem I have is the request is being sent to the server with:
GET /myapp/Scripts/test.js HTTP/1.1
Accept: text/ecmascript
...
But as .js files generally have a content type of application/javascript, the webserver responds with a 406 Not Accepted error.
How do I override the content type of static content in ASP.NET MVC?
I found the solution, simply add this to the web.config:
<system.webServer>
<staticContent>
<remove fileExtension=".js"/>
<mimeMap fileExtension=".js" mimeType="text/ecmascript"/>
</staticContent>
</system.webServer>

Dots in URL causes 404 with ASP.NET mvc and IIS

I have a project that requires my URLs have dots in the path. For example I may have a URL such as www.example.com/people/michael.phelps
URLs with the dot generate a 404. My routing is fine. If I pass in michaelphelps, without the dot, then everything works. If I add the dot I get a 404 error. The sample site is running on Windows 7 with IIS8 Express. URLScan is not running.
I tried adding the following to my web.config:
<security>
<requestFiltering allowDoubleEscaping="true"/>
</security>
Unfortunately that didn't make a difference. I just receive a 404.0 Not Found error.
This is a MVC4 project but I don't think that's relevant. My routing works fine and the parameters I expect are there, until they include a dot.
What do I need to configure so I can have dots in my URL?
I got this working by editing my site's HTTP handlers. For my needs this works well and resolves my issue.
I simply added a new HTTP handler that looks for specific path criteria. If the request matches it is correctly sent to .NET for processing. I'm much happier with this solution that the URLRewrite hack or enabling RAMMFAR.
For example to have .NET process the URL www.example.com/people/michael.phelps add the following line to your site's web.config within the system.webServer / handlers element:
<add name="ApiURIs-ISAPI-Integrated-4.0"
path="/people/*"
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
Edit
There are other posts suggesting that the solution to this issue is RAMMFAR or RunAllManagedModulesForAllRequests. Enabling this option will enable all managed modules for all requests. That means static files such as images, PDFs and everything else will be processed by .NET when they don't need to be. This options is best left off unless you have a specific case for it.
After some poking around I found that relaxedUrlToFileSystemMapping did not work at all for me, what worked in my case was setting RAMMFAR to true, the same is valid for (.net 4.0 + mvc3) and (.net 4.5 + mvc4).
<system.webserver>
<modules runAllManagedModulesForAllRequests="true">
Be aware when setting RAMMFAR true Hanselman post about RAMMFAR and performance
I believe you have to set the property relaxedUrlToFileSystemMapping in your web.config. Haack wrote an article about this a little while ago (and there are some other SO posts asking the same types of question)
<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
Edit
From the comments below, later versions of .NET / IIS may require this to be in the system.WebServer element.
<system.webServer>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
I got stuck on this issue for a long time following all the different remedies without avail.
I noticed that when adding a forward slash [/] to the end of the URL containing the dots [.], it did not throw a 404 error and it actually worked.
I finally solved the issue using a URL rewriter like IIS URL Rewrite to watch for a particular pattern and append the training slash.
My URL looks like this: /Contact/~firstname.lastname so my pattern is simply: /Contact/~(.*[^/])$
I got this idea from Scott Forsyth, see link below:
http://weblogs.asp.net/owscott/handing-mvc-paths-with-dots-in-the-path
Just add this section to Web.config, and all requests to the route/{*pathInfo} will be handled by the specified handler, even when there are dots in pathInfo. (taken from ServiceStack MVC Host Web.config example and this answer https://stackoverflow.com/a/12151501/801189)
This should work for both IIS 6 & 7. You could assign specific handlers to different paths after the 'route' by modifying path="*" in 'add' elements
<location path="route">
<system.web>
<httpHandlers>
<add path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" />
</httpHandlers>
</system.web>
<!-- Required for IIS 7.0 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</location>
MVC 5.0 Workaround.
Many of the suggested answers doesn't seem to work in MVC 5.0.
As the 404 dot problem in the last section can be solved by closing that section with a trailing slash, here's the little trick I use, clean and simple.
While keeping a convenient placeholder in your view:
#Html.ActionLink("Change your Town", "Manage", "GeoData", new { id = User.Identity.Name }, null)
add a little jquery/javascript to get the job done:
<script>
$('a:contains("Change your Town")').on("click", function (event) {
event.preventDefault();
window.location.href = '#Url.Action("Manage", "GeoData", new { id = User.Identity.Name })' + "/";
});</script>
please note the trailing slash, that is responsible for changing
http://localhost:51003/GeoData/Manage/user#foo.com
into
http://localhost:51003/GeoData/Manage/user#foo.com/
Super easy answer for those that only have this on one webpage. Edit your actionlink and a + "/" on the end of it.
#Html.ActionLink("Edit", "Edit", new { id = item.name + "/" }) |
Depending on how important it is for you to keep your URI without querystrings, you can also just pass the value with dots as part of the querystring, not the URI.
E.g. www.example.com/people?name=michael.phelps will work, without having to change any settings or anything.
You lose the elegance of having a clean URI, but this solution does not require changing or adding any settings or handlers.
You might want to think about using dashes instead of periods.
In Pro ASP MVC 3 Framework they suggest this about making friendly URLs:
Avoid symbols, codes, and character sequences. If you want a word
separator, use a dash (/my-great-article). Underscores are unfriendly,
and URL-encoded spaces are bizarre (/my+great+article) or disgusting
(/my%20great%20article).
It also mentions that URLs should be be easy to read and change for humans. Maybe a reason to think about using a dash instead of a dot also comes from the same book:
Don't use file name extensions for HTML pages (.aspx or .mvc), but do use them for specialized file types (.jpg, .pdf, .zip, etc). Web browsers don't care about file name extensions if you set the MIME type appropriately, but humans still expect PDF files to end with .pdf
So while a period is still readable to humans (though less readable than dashes, IMO), it might still be a bit confusing/misleading depending on what comes after the period. What if someone has a last name of zip? Then the URL will be /John.zip instead of /John-zip, something that can be misleading even to the developer that wrote the application.
Would it be possible to change your URL structure?
For what I was working on I tried a route for
url: "Download/{fileName}"
but it failed with anything that had a . in it.
I switched the route to
routes.MapRoute(
name: "Download",
url: "{fileName}/Download",
defaults: new { controller = "Home", action = "Download", }
);
Now I can put in localhost:xxxxx/File1.doc/Download and it works fine.
My helpers in the view also picked up on it
#Html.ActionLink("click here", "Download", new { fileName = "File1.doc"})
that makes a link to the localhost:xxxxx/File1.doc/Download format as well.
Maybe you could put an unneeded word like "/view" or action on the end of your route so your property can end with a trailing / something like /mike.smith/view
As solution could be also considering encoding to a format which doesn't contain symbol., as base64.
In js should be added
btoa(parameter);
In controller
byte[] bytes = Convert.FromBase64String(parameter);
string parameter= Encoding.UTF8.GetString(bytes);
It's as simple as changing path="." to path="". Just remove the dot in the path for ExensionlessUrlHandler-Integrated-4.0 in web.config.
Here's a nice article https://weblog.west-wind.com/posts/2015/Nov/13/Serving-URLs-with-File-Extensions-in-an-ASPNET-MVC-Application
Tried all the solutions above but none of them worked for me. What did work was I uninstalling .NET versions > 4.5, including all its multilingual versions; Eventually I added newer (English only) versions piece by piece. Right now versions installed on my system is this:
2.0
3.0
3.5 4
4.5
4.5.1
4.5.2
4.6
4.6.1
And its still working at this point. I'm afraid to install 4.6.2 because it might mess everything up.
So I could only speculate that either 4.6.2 or all those non-English versions were messing up my configuration.
I was able to solve my particular version of this problem (had to make /customer.html route to /customer, trailing slashes not allowed) using the solution at https://stackoverflow.com/a/13082446/1454265, and substituting path="*.html".
Add URL Rewrite rule to Web.config archive. You need to have the URL Rewrite module already installed in IIS. Use the following rewrite rule as inspiration for your own.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Add trailing slash for some URLs" stopProcessing="true">
<match url="^(.*(\.).+[^\/])$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Redirect" url="{R:1}/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Also, (related) check the order of your handler mappings. We had a .ashx with a .svc (e.g. /foo.asmx/bar.svc/path) in the path after it. The .svc mapping was first so 404 for the .svc path which matched before the .asmx.
Havn't thought too much but maybe url encodeing the path would take care of this.
This is the best solution I have found for the error 404 on IIS 7.5 and .NET Framework 4.5 environment, and without using: runAllManagedModulesForAllRequests="true".
I followed this thread: https://forums.asp.net/t/2070064.aspx?Web+API+2+URL+routing+404+error+on+IIS+7+5+IIS+Express+works+fine and I have modified my web.config accordingly, and now the MVC web app works well on IIS 7.5 and .NET Framework 4.5 environment.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
[RoutePrefix("File")]
[Route("{action=index}")]
public class FileController : Controller
{
// GET: File
public ActionResult Index()
{
return View();
}
[AllowAnonymous]
[Route("Image/{extension?}/{filename}")]
public ActionResult Image(string extension, string filename)
{
var dir = Server.MapPath("/app_data/images");
var path = Path.Combine(dir, filename+"."+ (extension!=null? extension:"jpg"));
// var extension = filename.Substring(0,filename.LastIndexOf("."));
return base.File(path, "image/jpeg");
}
}
}

Disable client side caching

I've been searching for info on how to disable client side caching on project level.
I know I can add the following before an action method:
[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
I also read something about making profiles for caching, but that would also mean refering to them in several places. I would like a single setting in web.config, or maybe in IIS?
The project I'm working on contains a lot of partial views
Thank you in advance for any advice in this matter.
You can disable browser caching via Web.Config:
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache, no-store" />
<add name="Pragma" value="no-cache" />
<add name="Expires" value="-1" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Source: http://blog.jamesjones.name/2009/11/how-to-disable-browser-caching-in.html
Edit: added no-store to Cache-Control for Chrome ( http://code.google.com/p/chromium/issues/detail?id=28035 )
You can set this at the project level or at the subdirectory level to control browser caching as desired. For example, in a primarily data-driven/dynamic site, I may set these headers at the project level, but in a /static directory (which contains my .js, .css, images), add another web.config which includes the appropriate </clear> directive, and perhaps set a far-future-expires header instead.
You could make BaseController and set your cache profile to it.
Then make all of your controllers to inherit from this BaseController.
Update:
Here is what I've :
// Here is my custom OutputCaheAttribute to prevent cache at all.
//Whatever you may put anything you want.
//Of course i don't use it here but i put it to show you how it's going.
[NoCache]
public class BaseController : Controller
{
protected override ViewResult View(string viewName, string masterName, object model)
{
// I do some stuffs here to change MasterPage depending on current culture.
// Don't care about it i just wanna show you why BaseController is good idea.
}
}
Then ALL my controllers inherits from this BaseController instead of normal Controller.
Hope this was helpful ;)
Expanding on #Tom's answer, for per file or per directory based cache busting :
<configuration>
<!-- disable cache for every file in this directory -->
<location path="dist">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0, s-maxage=0" />
<add name="Pragma" value="no-cache" />
<add name="Expires" value="-1" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
</configuration>
You can define cache profiles in web.config, however, using cache profiles doesn't seem to work with OutputCache attribute in mvc 3. Read this question: Caching ChildActions using cache profiles won't work?
The OutputCache attribute is used for server side output action output caching. To turn it off, you just don't apply the attribute to the action/controller. If you want to disable client side, then that is taken care of by adding a header informing the browser not to cache the result.
If you need to cache files in a subfolder for 1 day (24 hours), you can add a separate web.config to these sub folders (requires clearing client cache the first time).
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="00:24:00" />
</staticContent>
</system.webServer>
</configuration>
Try this
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]

Resources