Configure IISExpress 8 to use ASP.NET to handle requests for a .gif file? - iis

I'm trying to get a custom image handler for .gif files working in an MVC website on my development machine which runs Visual Studio 2013. I'm basing it on an article by Scott Hanselman in which he dynamically generates a png.
I have a class which inherits from IHttpHandler and implements a ProcessRequest method (I don't think the code is relevant so I'm not including it). I've added an entry to the web.config like this:
<system.webServer>
<handlers>
<add name="ImageHandler" verb="*" path="*.gif" type="StaticContentWorkbench.Infrastructure.CustomGIFHandler" />
Unfortunately this isn't working so I did some research and found out that I probably need to alter the IIS configuration so that .gif files are handled by ASP.NET. I tried adding an entry to the system.webserver - handlers section of the IISExpress application.config file just before the last entry:
<add name="PageHandlerFactory-ISAPI-4.0_64bit_Add_Gifs" path="*.gif" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
However this hasn't worked either and now I'm pretty much stuck.
How do I correctly configure IISExpress 8 to use ASP.NET to handle requests for a .gif file?

I had the same problem,
what worked for me was this
<system.webServer>
<handlers>
<add verb="GET,HEAD" name="DocHandler"
path="*.pdf"
type="Web.DocHandler" />
</handlers>
</system.webServer>
Problem is that you need to map every extension singularly, you cannot put multiple extension in the path property.
In your case, try to specify the verbs you need instead of *
Hope this helps

Related

Enable Compression Mime-types for Web-Site Application

Our website uses both dynamic and static compression. I know that compression can be enabled/disabled on a web.config level, but that the mime-types for static and dynamic compression cannot be enabled at a web-config level.
Meaning, this section:
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" staticCompressionIgnoreHitFrequency="true">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
<staticTypes>
Stuff
</staticTypes>
<dynamicTypes>
Stuff
</dynamicTypes>
</httpCompression>
Must go in the applicationHost.config, and is generally edited using appcmd.exe.
I know there is a location element in the applicationHost.config that allows setting many things on a per website basis, but I can't seem to find anywhere if mimetypes for dynamic compression are one of them.
I have tried overriding these settings using a location element, but have not had any success and cannot find documentation stating it's possible for the httpCompression element.
To make matters worse, we install our product as a web application under the default site, so really we want to enable these dynamic compression mime-types only under our application, instead of site (or server) wide. Is this possible?
Generally, we are using IIS 7 and above. Right now our minimum is 7, so assume anything needs to work with that.
My question is:
Can httpCompression settings be set in the applicationHost.config per website and possible per web application under a web site?
Is there a different way to enable dynamicCompression specifics on a website/web application level?
Just an important precision: There is one prerequisite to ensure that you can add MIME Types in the "web.config" file:
It is possible to add MIME Types in the <staticTypes> and <dynamicTypes> sections at the website level (in "web.config") only if this is explicitely allowed at the "applicationHost.config" level, as explained in this solution from Stack Overflow:
The important thing to note is that modifying your
applicationHost.config (in %windir%\system32\inetsrv\config) from the following setting:
<section name="httpCompression" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
to:
<section name="httpCompression" overrideModeDefault="Allow" />
will enable configuration of the httpCompression tag under the
system.webServer tag in your web.config.
Yes you can very well add dynamic and static types in web application's web.config file. ApplicationHost.config will define global compression settings and if you want to override them in your application you can do so. Following is sample from one of my application.
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
</handlers>
<httpCompression>
<dynamicTypes>
<remove mimeType="text/*" />
<add mimeType="application/json" enabled="true" />
</dynamicTypes>
</httpCompression>
Here remove tag in dynamicTypes removes global entry coming from ApplicationHost.config
add tag is adding additional mimeType on top of global entries from applicationHost.config. This addition will be applicable only for whose web.config is being modified.
Similarly you can modify staticTypes as well.

Cannot get caching for static recources (CSS, images) does to work in Azure Web App

I have an Azure account with a Web Application that is in the very early stages of development.
I am using Google Pagespeed Insights to test for any performance issues ( https://developers.google.com/speed/pagespeed/insights/ )
It tells me I don't have the cache set for my static resources. So I have enabled caching in the web.config file for my web application by adding the following code:
<system.webServer>
<staticContent>
<clientCache cacheControlCustom="public" cacheControlMaxAge="00.12:00:00" cacheControlMode="UseMaxAge" />
</staticContent>
</system.webServer>
Yet this does not work (I check the headers with Chrome Dev Tools).
Any ideas on what I am doing wrong?
Thank you.
Never mind, got it figured out.
Had to take out the following code out of web.config:
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
It was there from the ASP.NET 5 MVC project I set up earlier.

MVC WebAPI2 attribute routing using a path ending with a route parameter of type double

We are having an issue with WebApi2 attribute routing. We recently upgraded to MVC5 and Web Api 2. As part of the upgrade we shifted our Web Api to use Attribute routing.
One of our API calls allows for data to be requested using a latitude and longitude bounding box.
https://myapi.com/v1/things/area/{toplat}/{leftlon}/{botlat}/{rightlon}
This worked in the previous api, but not in the new one. We can't find a configuration that allows this to work. The final argument {rightlon} is a double and the xx.XXX is interpreted as a file extension.
Specifying the parameters as a double {toplat:double} had no impact. We can't easily force the legacy clients to update to include a trailing slash as some posts suggest. This config change also didn't work for us.
Why is my Web API method with double args not getting called?
Has anyone found a way to use attribute routing in WebApi2 to allow for a route that has a double/decimal/float as the last route parameter?
Solved.
The linked article did include the solution but also needed the correct format on the Attribute Routing.
[HttpGet] [Route("~/v1/things/area/{toplat:double}/{leftlon:double}/{botlat:double}/{rightlon:double}")]
in the web.config
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
</system.webServer>

How to ignore a route with self-hosted ServiceStack

I am currently working on a solution where we have a self-hosted ServiceStack layer running, but the problem is that I keep getting errors when I access it from the browser and the browser tries to get the favicon. As far as I can see there is no option of ignoring a specific route when running self-hosted?
I would have imagined something like
Routes.Ignore("favicon*")
a bit like the
Routes.Add<Foo>("/foo")
in my AppHost Configure method
In my web.config I like to have something like this
<handlers>
<add verb="*" path="*.*" type="System.Web.StaticFileHandler" name="files" />
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true"/>
</handlers>
That way all files with an extension get handled by IIS and means you don't have to go all the way through the aspnet pipeline to server up a 404. It also means you don't log a load of 404s in your servicestack application.
Unlike MVC which uses a Http Module to process and hijack all requests, ServiceStack is built-on ASP.NET's raw IHttpHandler interfaces. This means ServiceStack must handle any request matching the ServiceStack handler path (e.g. / or /api) by returning an IHttpHandler and isn't able to Ignore them like they do in MVC.
You can however catch and handle all unhandled requests by registering a handler in IAppHost.CatchAllHandlers, e.g:
appHost.CatchAllHandlers.Add((httpMethod, pathInfo, filePath) => {
if (pathInfo.StartsWith("favicon"))
return new NotFoundHttpHandler();
});
Just to append to #antonydenyer's answer. His solution seems to work also when combining owin with servicestack3.
<handlers>
<add path="auth/*" name="Microsoft.Owin.Host.SystemWeb" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
Here SS is handling every request except /auth. Auth is mapped to Identityserver3 using owin.

ASP.NET Web API returns 404 for PUT only on some servers

I have written a site that uses ASP.NET MVC Web API and everything is working nicely until I put it on the staging server. The site works fine on my local machine and on the dev web server. Both dev and staging servers are Windows Server 2008 R2.
The problem is this: basically the site works, but there are some API calls that use the HTTP PUT method. These fail on staging returning a 404, but work fine elsewhere.
The first problem that I came across and fixed was in Request Filtering. But still getting the 404.
I have turned on tracing in IIS and get the following problem.
168. -MODULE_SET_RESPONSE_ERROR_STATUS
ModuleName IIS Web Core
Notification 16
HttpStatus 404
HttpReason Not Found
HttpSubStatus 0
ErrorCode 2147942402
ConfigExceptionInfo
Notification MAP_REQUEST_HANDLER
ErrorCode The system cannot find the file specified. (0x80070002)
The configs are the same on dev and staging, matter of fact the whole site is a direct copy.
Why would the GETs and POSTs work, but not the PUTs?
For those of you who do not have WebDAV enabled but are still running into this issue using MVC 4's Web API's...
Steve Michelotti documented a solution that worked for me here.
At the end of the day, I enabled all verbs (verb="*") to the ExtensionlessUrlHandler-Integrated-4.0 handler in my web config.
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Those IIS servers have web-dav module installed on them and i bet it is not needed and it was installed because the person installing ticked all boxes.
Just remove web-dav from iis.
Alternatively use web.config to remove web dav module:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
...
It seems there are a number of reasons that this occurs. None of the above quite worked for me. I already had the ExtensionlessUrlHandler settings in web.config with all the required HTTP verbs. In the end I had to make the following changes in IIS:
In IIS select your website and double-click Handler Mappings
Find ExtensionlessUrlHandler-ISAPI-4.0_32bit and double-click
In the dialog that appears, click Request Restrictions
On the Verbs tab add the missing HTTP verbs separated by commas (in my case it was PUT and DELETE
Click Ok where required and answer Yes in the Edit Script Map dialog that pops up.
Repeat for ExtensionlessUrlHandler-ISAPI-4.0_64bit
Hope this helps somebody :)
My hosting provider could NOT uninstall WebDAV as this would affect everyone.
This, runAllManagedModulesForAllRequests="true" , worked but was not recommended.
Many fixes included removing the module for WebDAVModule but that still didn't work. I removed the handler also, and finally I could use all verbs POST GET PUT DELETE.
Remove WebDAVModule and WebDAV in modules and handlers.
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
I fixed this removing the UrlScan ISAPI filter
In my case, none of these solutions applied.
I fixed it by changing my app pool to Integrated instead of Classic.
The handler:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
is not going to work with a Classic app pool, since its preCondition is integratedMode.
Rick Strahl from West-Wind recommended the following:
< handlers>
< remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
< add name="ExtensionlessUrlHandler-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0"
/>
< /handlers>
Which Worked very well for me.
Hi For me none of the solutions worked. I finally got it working doing this :
1) In IIS select you application.
2) Go to Request Filtering
3) Then select the HTTP Verbs tab
4) I found the PUT and other verbs to have allowed to false but wasn't able to just edit so I removed the verb then either in the pane on the right select allow verb or right click on the list and select it. Enter the verb you're having troubles with and voilĂ  !
Hope this will help someone !
I resolved this by changing my application pool for the website to Integrated mode when it was previously on Classic mode.

Resources