Apache to IIS web.config? - caching

I am used to working with Apache or NGINX, but a new client has its website on a Microsoft IIS server that makes use of web.config where he would like to add caching.
I normally use the following setup:
### Begin Caching Performance ###
# Use UTF-8 encoding for anything served text/plain or text/html
AddDefaultCharset UTF-8
# Force UTF-8 for a number of file formats
<IfModule mod_mime.c>
AddCharset UTF-8 .atom .css .js .json .rss .vtt .xml
</IfModule>
# FileETag None is not enough for every server.
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
# Since we’re sending far-future expires, we don’t need ETags for static content.
FileETag None
<IfModule mod_alias.c>
<FilesMatch "\.(html|htm|rtf|rtx|txt|xsd|xsl|xml)$">
<IfModule mod_headers.c>
Header unset Pragma
Header append Cache-Control "public"
Header unset Last-Modified
</IfModule>
</FilesMatch>
<FilesMatch "\.(css|htc|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$">
<IfModule mod_headers.c>
Header unset Pragma
Header append Cache-Control "public"
</IfModule>
</FilesMatch>
</IfModule>
# Gzip Compression
<IfModule mod_deflate.c>
# Force compression for mangled headers.
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
# Don’t compress images and other uncompressible content
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|rar|zip|exe|flv|mov|wma|mp3|avi|swf|mp?g|mp4|webm|webp|pdf)$ no-gzip dont-vary
</IfModule>
</IfModule>
# Compress all output labeled with one of the following MIME-types
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE "application/atom+xml" \
"application/javascript" \
"application/json" \
"application/ld+json" \
"application/manifest+json" \
"application/rdf+xml" \
"application/rss+xml" \
"application/schema+json" \
"application/vnd.geo+json" \
"application/vnd.ms-fontobject" \
"application/x-font-ttf" \
"application/x-javascript" \
"application/x-web-app-manifest+json" \
"application/xhtml+xml" \
"application/xml" \
"font/eot" \
"font/opentype" \
"image/bmp" \
"image/svg+xml" \
"image/vnd.microsoft.icon" \
"image/x-icon" \
"text/cache-manifest" \
"text/css" \
"text/html" \
"text/javascript" \
"text/plain" \
"text/vcard" \
"text/vnd.rim.location.xloc" \
"text/vtt" \
"text/x-component" \
"text/x-cross-domain-policy" \
"text/xml"
</IfModule>
<IfModule mod_headers.c>
Header append Vary: Accept-Encoding
</IfModule>
</IfModule>
<IfModule mod_mime.c>
AddType text/html .html_gzip
AddEncoding gzip .html_gzip
</IfModule>
<IfModule mod_setenvif.c>
SetEnvIfNoCase Request_URI \.html_gzip$ no-gzip
</IfModule>
# Expires headers
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
# cache.appcache needs re-requests in FF 3.6
ExpiresByType text/cache-manifest "access plus 0 seconds"
# CSS
ExpiresByType text/css "access plus 1 year"
# Data interchange
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
# Favicon (cannot be renamed!)
ExpiresByType image/x-icon "access plus 1 week"
# HTML components (HTCs)
ExpiresByType text/x-component "access plus 1 month"
# HTML
ExpiresByType text/html "access plus 0 seconds"
# JavaScript
ExpiresByType application/javascript "access plus 1 year"
# Manifest files
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
ExpiresByType text/cache-manifest "access plus 0 seconds"
# Media
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# Web feeds
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
# Web fonts
ExpiresByType application/font-woff "access plus 1 month"
ExpiresByType application/font-woff2 "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
</IfModule>
# Send CORS headers if browsers request them; enabled by default for images.
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
# mod_headers
<FilesMatch "\.(gif|png|jpe?g|svg|svgz|ico|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
# Webfont access
<IfModule mod_headers.c>
<FilesMatch "\.(tt[cf]|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
### End Caching Performance ###
So this or at least some parts to GZIP and Expiration Headers I would like to add to this website to make it more performant. Does anyone know how I would be able to convert or at least point me in the right direction to convert the above performance and caching code to Microsoft IIS's web.config?
Thanks in advance for more information!

In the end I have configured the web.config like this, the reason I am doing it directly via the web.config is that the client does not have access to the IIS control panel nor does the host company want to provide it.
This is the code I eventually came up with:
<!-- General Optimisation-->
<directoryBrowse enabled="false"/>
<!-- Security Headers -->
<httpProtocol>
<customHeaders>
<add name="Security-By" value="Sandhills Studio"/>
<add name="Content-Security-Policy" value="img-src 'self' https: data: blob:; font-src 'self' https: data:;"/>
<add name="X-Frame-Options" value="SAMEORIGIN"/>
<add name="X-XSS-Protection" value="1; mode=block"/>
<add name="Referrer-Policy" value="no-referrer-when-downgrade"/>
<add name="Expect-CT" value="max-age=86400,enforce"/>
<add name="Feature-Policy" value="fullscreen *;camera 'none';microphone 'none'"/>
<add name="X-Content-Type-Options" value="nosniff"/>
<add name="Strict-Transport-Security" value="max-age=15552000; includeSubDomains; preload"/>
<!--Remove Headers-->
<remove name="X-Powered-By"/>
<remove name="X-Powered-By-Plesk"/>
<remove name="Pragma"/>
<remove name="ETag"/>
</customHeaders>
</httpProtocol>
<!-- GZip static file content -->
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="512">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="10"/>
<dynamicTypes>
<add mimeType="text/*" enabled="true"/>
<add mimeType="message/*" enabled="true"/>
<add mimeType="application/javascript" enabled="true"/>
<add mimeType="application/json" enabled="true"/>
<add mimeType="image/svg+xml" enabled="true"/>
<add mimeType="application/font-woff" enabled="true"/>
<add mimeType="application/x-font-ttf" enabled="true"/>
<add mimeType="application/octet-stream" enabled="true"/>
<add mimeType="*/*" enabled="false"/>
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true"/>
<add mimeType="message/*" enabled="true"/>
<add mimeType="application/atom+xml" enabled="true"/>
<add mimeType="application/javascript" enabled="true"/>
<add mimeType="application/json" enabled="true"/>
<add mimeType="application/ld+json" enabled="true"/>
<add mimeType="application/manifest+json" enabled="true"/>
<add mimeType="application/rdf+xml" enabled="true"/>
<add mimeType="application/rss+xml" enabled="true"/>
<add mimeType="application/schema+json" enabled="true"/>
<add mimeType="application/vnd.geo+json" enabled="true"/>
<add mimeType="application/vnd.ms-fontobject" enabled="true"/>
<add mimeType="application/x-font-ttf" enabled="true"/>
<add mimeType="application/x-javascript" enabled="true"/>
<add mimeType="application/x-web-app-manifest+json" enabled="true"/>
<add mimeType="application/xhtml+xml" enabled="true"/>
<add mimeType="application/xaml+xml" enabled="true"/>
<add mimeType="application/xml" enabled="true"/>
<add mimeType="application/font-woff" enabled="true"/>
<add mimeType="application/x-font-ttf" enabled="true"/>
<add mimeType="application/octet-stream" enabled="true"/>
<add mimeType="font/eot" enabled="true"/>
<add mimeType="font/opentype" enabled="true"/>
<add mimeType="image/bmp" enabled="true"/>
<add mimeType="image/svg+xml" enabled="true"/>
<add mimeType="image/vnd.microsoft.icon" enabled="true"/>
<add mimeType="image/x-icon" enabled="true"/>
<add mimeType="*/*" enabled="false"/>
</staticTypes>
</httpCompression>
<urlCompression doStaticCompression="true" doDynamicCompression="true"/>
<!-- Clinet Cache Control -->
<staticContent>
<!-- Set expire headers to 30 days for static content-->
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" setEtag="false"/>
<!-- use utf-8 encoding for anything served text/plain or text/html -->
<remove fileExtension=".air"/>
<mimeMap fileExtension=".air" mimeType="application/vnd.adobe.air-application-installer-package+zip"/>
<remove fileExtension=".css"/>
<mimeMap fileExtension=".css" mimeType="text/css"/>
<remove fileExtension=".js"/>
<mimeMap fileExtension=".js" mimeType="text/javascript"/>
<remove fileExtension=".json"/>
<mimeMap fileExtension=".json" mimeType="application/json"/>
<remove fileExtension=".rss"/>
<mimeMap fileExtension=".rss" mimeType="application/rss+xml; charset=UTF-8"/>
<remove fileExtension=".html"/>
<mimeMap fileExtension=".html" mimeType="text/html; charset=UTF-8"/>
<remove fileExtension=".xml"/>
<mimeMap fileExtension=".xml" mimeType="application/xml; charset=UTF-8"/>
<!-- HTML5 Audio/Video mime types-->
<remove fileExtension=".mp3"/>
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg"/>
<remove fileExtension=".mp4"/>
<mimeMap fileExtension=".mp4" mimeType="video/mp4"/>
<remove fileExtension=".ogg"/>
<mimeMap fileExtension=".ogg" mimeType="audio/ogg"/>
<remove fileExtension=".ogv"/>
<mimeMap fileExtension=".ogv" mimeType="video/ogg"/>
<remove fileExtension=".webm"/>
<mimeMap fileExtension=".webm" mimeType="video/webm"/>
<!-- Proper svg serving. Required for svg webfonts on iPad -->
<remove fileExtension=".svg"/>
<mimeMap fileExtension=".svg" mimeType="image/svg+xml"/>
<remove fileExtension=".svgz"/>
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml"/>
<!-- Remove default IIS mime type for .eot which is application/octet-stream -->
<remove fileExtension=".eot"/>
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject"/>
<remove fileExtension=".ttf"/>
<mimeMap fileExtension=".ttf" mimeType="application/x-font-ttf"/>
<remove fileExtension=".ttc"/>
<mimeMap fileExtension=".ttc" mimeType="application/x-font-ttf"/>
<remove fileExtension=".otf"/>
<mimeMap fileExtension=".otf" mimeType="font/opentype"/>
<remove fileExtension=".woff"/>
<mimeMap fileExtension=".woff" mimeType="application/x-font-woff"/>
<remove fileExtension=".woff2"/>
<mimeMap fileExtension=".woff2" mimeType="application/x-font-woff2"/>
<remove fileExtension=".less"/>
<mimeMap fileExtension=".less" mimeType="text/css"/>
<remove fileExtension=".crx"/>
<mimeMap fileExtension=".crx" mimeType="application/x-chrome-extension"/>
<remove fileExtension=".xpi"/>
<mimeMap fileExtension=".xpi" mimeType="application/x-xpinstall"/>
<remove fileExtension=".safariextz"/>
<mimeMap fileExtension=".safariextz" mimeType="application/octet-stream"/>
<!-- Flash Video mime types-->
<remove fileExtension=".flv"/>
<mimeMap fileExtension=".flv" mimeType="video/x-flv"/>
<remove fileExtension=".f4v"/>
<mimeMap fileExtension=".f4v" mimeType="video/mp4"/>
<!-- Assorted types -->
<remove fileExtension=".ico"/>
<mimeMap fileExtension=".ico" mimeType="image/x-icon"/>
<remove fileExtension=".webp"/>
<mimeMap fileExtension=".webp" mimeType="image/webp"/>
<remove fileExtension=".htc"/>
<mimeMap fileExtension=".htc" mimeType="text/x-component"/>
<remove fileExtension=".vcf"/>
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard"/>
<remove fileExtension=".torrent"/>
<mimeMap fileExtension=".torrent" mimeType="application/x-bittorrent"/>
<remove fileExtension=".cur"/>
<mimeMap fileExtension=".cur" mimeType="image/x-icon"/>
<remove fileExtension=".webapp"/>
<mimeMap fileExtension=".webapp" mimeType="application/x-web-app-manifest+json; charset=UTF-8"/>
</staticContent>
Sadly SVG isn't being GZipped, even though listed is on a lower level that this has to be included as it seems IIS doesn't recognise this mime type by default.
If anyone has any suggestions, feel free to let me know!

Related

Laravel 5.5 Error 405 (Method Not Allowed) XHR PUT METHOD now working on Azure Server

I have installed Laravel 5.5 on Azure Web Server with PHP 7 installed.
Other request methods working well except the XHR PUT METHOD. It returns an error message on the console: 405 (Method Not Allowed) and XHR network preview: The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.
I already allowed the PUT method on web.config files
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="true"/>
<staticContent>
<remove fileExtension=".svg" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
</staticContent>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,DELETE,PUT,PATCH" />
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<rule name="Laravel5" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" appendQueryString="true" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<requestLimits maxQueryString="10000" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
Please kindly help me.
Thanks
I have found the answer, by this question. stackoverflow.com/a/25171782/2544756 by adding this code to system.Webserver
<handlers>
<remove name="PHP71_via_FastCGI" />
<add name="PHP71_via_FastCGI" path="*.php" verb="GET,PUT,POST,DELETE,HEAD,OPTIONS,TRACE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK" modules="FastCgiModule" scriptProcessor="D:\Program Files (x86)\PHP\v7.1\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>
But I need to change the PHP version to 7.1
Hope it

How to make an HTTP PUT with a param in an ionic 2 app to a WebAPI?

I am trying to make an HTTP PUT with an integer parameter to a MVC WebApi.
I tried to follow the angular 2 guidelines for HTTP PUT: https://angular.io/docs/ts/latest/guide/server-communication.html
My WebApi:
public IHttpActionResult Put([FromBody]int id)
{
return Ok();
}
My Http PUT in my service in my ionic 2 app:
makePut(){
let body = JSON.stringify({id:155320});
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return new Promise(resolve => {
this.http.put('API_URL', body, options)
.subscribe(
response => {
console.log(response.text());
},
error => {
//Failed to Login.
alert(error.text());
console.log(error.text());
});
});
}
And finally the call to my service from my home page:
this.service.makePut().then(data => {console.log(data);});
When I run this I get a 405 method not allowed. Is there anything I am missing?
UPDATE here is part of the web.config in my web api:
<system.webServer>
<security>
</security>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="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>
</system.webServer>
It might be Web Api error and you can resolve that by adding this code to your web.config file
<handlers accessPolicy="Read, Script">
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64"
responseBufferLimit="0" />
this article can give you more information about 405 error.
I was able to fix the problem, which turned out to be a CORS issue. You can view how to disable same origin policy in Chrome here: How to resolve CORS issue and JSONP issue in Ionic2
Once I disabled it in chrome, the HTTP PUT succeed.
Here is my final code:
makePut(){
let body = 155320; // this is different
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return new Promise(resolve => {
this.http.put('API_URL', body, options)
.subscribe(
response => {
console.log(response.text());
},
error => {
//Failed to Login.
alert(error.text());
console.log(error.text());
});
});
}

how do i access the elmah log when used in web api

I installed elmah as described here https://github.com/rdingwall/elmah-contrib-webapi
Now I am trying to access the logging but I keep getter error 404 errors.
Am I using the correct url ? Is there still some configuration missing ?
My webapi runs as follows :
http://localhost/MagnusREST/api/Customers/054036?frmt=xml
My application_start looks like this :
protected void Application_Start()
{
GlobalConfiguration.Configuration.Filters.Add(new ElmahHandleErrorApiAttribute()); //added for elmah
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
my webapi config remained unchanged and looks like this :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.MediaTypeMappings.Add(
new QueryStringMapping("frmt", "json",
new MediaTypeHeaderValue("application/json")));
config.Formatters.XmlFormatter.MediaTypeMappings.Add(
new QueryStringMapping("frmt", "xml",
new MediaTypeHeaderValue("application/xml")));
//config.Formatters.Clear();
JsonMediaTypeFormatter oldformatter = config.Formatters.Where(f => f is JsonMediaTypeFormatter).FirstOrDefault() as JsonMediaTypeFormatter;
if (oldformatter != null) config.Formatters.Remove(oldformatter);
config.Formatters.Insert(0,new PartialJsonMediaTypeFormatter() { IgnoreCase = true });
}
}
Accessing logs via http://localhost/MagnusREST/api/elmah.axd does not work, via http://localhost/MagnusREST/elmah.axd does not work and http://localhost/elmah.axd does not work either.
What am I doing wrong?
This is running in visual studio 2013.
There was a missing piece in the web.config
<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" />
<add name="elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
The elma handler needs to be added. After doing that I could access the elmah log using followin url :
http://localhost/MagnusREST/elmah.axd
You have to read the documentation and questions both for elmah and the webapi contrib it seems. Ok the first problem is passed, what will be the next ;-)
To get is fully working more is needed than the above
Add configsections
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
</sectionGroup>
</configSections>
Add the elmah configuration you like for instance to send mails :
<elmah>
<security allowRemoteAccess="0" />
<errorMail from="xxxx" to="xxx" subject="some error" async="true"
smtpPort="25" smtpServer="xxx" userName="xxx" password="xxx"/>
</elmah>
The system.web and system.webserver need to be something like this :
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/>
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="Elmah.ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="Elmah.ErrorMail" type="Elmah.ErrorMailModule" preCondition="managedHandler" />
</modules>
<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" />
<add name="elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
</system.webServer>
Take a good look where elmah is being mentioned and add those things to your own configuration file that might look slightly different.
I also had to add this to my web.config and they it worked
<location path="elmah.axd" inheritInChildApplications="false">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<!--
See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for
more information on using ASP.NET authorization securing ELMAH.
<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>
-->
</system.web>
<system.webServer>
<handlers>
<add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>

Compression of OData in IIS

I use dynamic compression in IIS7 and enabled the following lines in the configuration:
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/json; charset=utf-8" enabled="true" />
<add mimeType="application/json; odata=fullmetadata; charset=utf-8" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimetype="application/atom+xml" enabled="true">
<add mimetype="application/atom+xml;charset=utf-8" enabled="true">
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
</httpCompression>
I have an OData controller in Web API which is based off a ODataController.
The OData part work fine, but dynamic compression seems not to work on them, the request looks like this:
Accept:application/atomsvc+xml;q=0.8, application/json;odata=fullmetadata;q=0.7, application/json;q=0.5, */*;q=0.1
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,nl;q=0.6
Connection:keep-alive
DataServiceVersion:3.0
MaxDataServiceVersion:3.0
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
X-SchemaVersion:2.0.0.265
And the response like this:
Cache-Control:no-cache
Content-Length:34862
Content-Type:application/json; odata=fullmetadata; charset=utf-8
DataServiceVersion:3.0
Date:Wed, 11 Jun 2014 16:35:12 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
I suppose the config you posted are web.config of your application. The most easy solution is to changed "add mimeType="/" enabled="false"" to "add mimeType="/" enabled="true"" in dynamicTypes of config. You can try if it works.
Another solution is to change the config in IIS manager. you can follow:Here

Requested resource does not support http method "PUT"

I'm using AttributeRouting with my Web API (MVC 4).
Why does this work?
[AcceptVerbs("PUT")]
[PUT("api/v1/tokens/current")]
public MemoryToken UpdateToken([FromBody] DeviceTokenViewModel viewModel)
{...}
And this one does not?
[PUT("api/v1/tokens/current")]
public MemoryToken UpdateToken([FromBody] DeviceTokenViewModel viewModel)
{...}
Error message: The requested resource does not support http method "PUT".
Why do I have to explicitly accept the PUT verb?
I'm just confused because something similar with POST works just fine (I don't have to specify the accepted verbs):
[POST("api/v1/tokens")]
public MemoryToken CreateToken()
{...}
From various other posts I believe it has to do with the setting in my web.config. The web server section currently looks like this:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="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" />
<add name="AttributeRouting" path="routes.axd" verb="*" type="AttributeRouting.Web.Logging.LogRoutesHandler, AttributeRouting.Web" />
</handlers>
I tried a couple things like removing WebDav and stuff. But nothing worked so far (unless explicitly allowing the PUT verb in the annotation).
Oh, I am using Visual Studios built-in development server.
Thanks guys!
In this link they describe the POST method as being the default if none of the actions match. So that's why it still works for your CreateToken() method without an HttpPost attribute .
You can specify the HTTP method with an attribute: AcceptVerbs, HttpDelete, HttpGet, HttpHead, HttpOptions, HttpPatch, HttpPost, or HttpPut.
Otherwise, if the name of the controller method starts with "Get", "Post", "Put", "Delete", "Head", "Options", or "Patch", then by convention the action supports that HTTP method.
If none of the above, the method supports POST.

Resources