ASP.NET / MVC: No owin.Environment item was found in the context - asp.net-mvc

I am doing a ASP.NET MVC web application with VS2013. The machine is Windows Server Enterprise, SP2 and IIS 7.
I got the following error:
Server Error in '/' Application.
No owin.Environment item was found in the context.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: No owin.Environment item was found in the context.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: No owin.Environment item was found in the context.]
I googled and found a solution and did something like this (by adding <add name="OWIN".... >) in web.config:
<system.webServer>
<modules >
<remove name="FormsAuthenticationModule" />
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
<handlers>
<add name="OWIN" path="*" verb="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler" />
</handlers>
</system.webServer>
After doing this, the web app works. However, all the static files such as CSS and Javascript are not found by the browser (404 on all of them), and so my app is style-less.
What is the correct way of configuring
<handlers>
<add name="OWIN" path="*" verb="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler" />
</handlers>
to get my app work right? Or I need do something else?
Thanks!

I got it working after many tests. Here is what I did:
<add name="OWIN" path="/Account/*" verb="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler" />
Please note the above path attribute that has a specific path. All my javascript and css files are under other top-level directories.
I am no ASP.NET/MVC expert. If someone has better ideas, please let me know!
Cheers.

Related

Why can I remove ExtensionlessUrlHandler from an MVC application without any ill effects?

I am trying to streamline my MVC application and deleting as much as possible. Can someone explain to me what this code below does in the web.config file in the root of the application. I have commented it out and still managed to run the application...
<system.webServer>
<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>
...
I have looked at this question: ASP.NET MVC 4 and ExtensionlessUrlHandler which has an answer that links to this blog: https://web.archive.org/web/20100611160242/http://blogs.msdn.com/b/tmarq/archive/2010/05/26/how-extensionless-urls-are-handled-by-asp-net-v4.aspx but I don't find it to explain my question.
I am using: IIS 8, ASP.NET MVC 4, .NET 4.5 in both development and production
You should check your web.config file. If the following setting is present
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>
Then, it could explain why everything is still working after deleting the ExtensionlessUrlHandler handlers.
By default the runAllManagedModulesForAllRequests is false which means that IIS does not delegate each request to managed (.NET) modules.
The core module which knows how to handle extension less URL is named UrlRouting module and it is a managed (not native) module. This means that it doesn't have a chance to handle the request and IIS internally tries to handle it according to its handler mapping configuration.
BTW, the default configuration treat the extensionless url as a static resource and therefore fails with 403.14 status code (in most cases)
When runAllManagedModulesForAllRequests is true any request being sent to IIS is directed to any managed module. The UrlRouting module has a change to process the request and delegate it to ASP.NET MVC.
To summarize, when running ASP.NET MVC applications you have two options
runAllManagedModulesForAllRequests is false. The ExtensionlessUrlHandler must be registered
runAllManagedModulesForAllRequests is true. You can delete ExtensionlessUrlHandler from the IIS handlers list
IIS express uses different handlers names than IIS
Add the following markup and it should disable the extensionless handlers for IIS express only
<remove name="ExtensionlessUrl-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrl-Integrated-4.0" />

IIS hijacks CORS Preflight OPTIONS request

I am making a CORS POST request and setting the Content-Type header to json. This triggers a Preflight OPTIONS request to fire (this is good and expected)
This OPTIONS request is responded to with a 200 OK but this isn't coming from my WebAPI application.
I have a custom Message Handler in place and it never get's hit so the request is getting responded to by IIS prior to hitting ASP.NET it seems.
I have found several posts on the subject and they say the following
Make sure WebDav is uninstalled / removed / disabled - DONE
Make sure the OPTIONSVerbHandler is removed / changed to use aspnet_isapi.dll - TRIED BOTH
Make sure the extensionlessURLHandler includes the OPTIONS verb - DONE
However, my options request is still getting hijacked. By that I mean, IIS responds with at 200 OK but isn't including an Access-Control-Allow-Origin header in the response. It isn't including this header because it is never getting to my WebAPI CORS code that would set this header.
The two best posts I could find that sound like my issue are
here: JQuery stuck at CORS preflight and IIS ghost response
and here: http://brockallen.com/2012/10/18/cors-iis-and-webdav/
I have tried turning on Failed Request tracing (FERB) in IIS and set it to trace all 200 status codes. I don't ever see the options request being logged... Not sure if this means FERB doesn't track OPTIONS requests or if I need to change something in the FERB settings to make it track OPTIONS requests, Or if this is a clue to what my problem is?
This is ASP.NET WebAPI 2.0 running on IIS 7.5 (Also tested on IIS 8 and IISExpress with same results)
Doesn't matter what browser (Chrome, FF, and IE all fail the same way)
I have tried everything I can find on the subject and still can't fix my problem.
Help me StackOverflow, you're my only hope.
A couple of things you can try here, all web.config related, firstly modify your modules element to include the attribute runAllManagedModulesForAllRequests="true", as below:
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDavModule" />
</modules>
Then set your handlers to the below:
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="WebDav" />
<remove name="OPTIONSVerbHandler" />
<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>
This should do the trick, but if it doesn't, as a last resort you can force IIS to output the correct headers with the below:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
Be wary of the wildcard value, you should really set this to the domain name that your site will be hosted on.
that's what worked for me after 4 hours of searching/experimenting:
<handlers>
<remove name="OPTIONSVerbHandler" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\System32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="None" />
</handlers>
I tried all of the above suggestions as well as others I found on SO and what mattered in my situation was we had Request Filtering enabled on IIS and the OPTIONS HTTP Verb was not in the list of allowed verbs. Once I added it I was able to sort out the rest of it.
I had the same issue and the following web.config settings fixed it for me.
<modules runAllManagedModulesForAllRequests="false">
<remove name="FormsAuthenticationModule" />
</modules>
<handlers>
<remove name="OPTIONSVerbHandler" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
I was then able to handle CORS OPTIONS requests manually in Application_BeginRequest.
I was originally using the library detailed in this blog post for handling CORS requests. The product I'm working on requires that runAllManagedModulesForAllRequests be set to false, though. This is why I had to set up a custom implementation, but if you don't have that requirement you should give that library a try. It worked great when I was able to have runAllManagedModulesForAllRequests set to true.
In our case it was request filtering in IIS disabling OPTIONS verb at the root web application level. Open up IIS Manager, click on root application, click on Request Filtering, if OPTIONS appears in list either remove or Allow Verb. Wish I had checked this first as lots of wasted time.
In my case, I missed the Microsoft.WebApi.Cors package.
Installed this package and configured it like so in the WebApiConfig class:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.EnableCors(new EnableCorsAttribute("*","*","*"));
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Please fine-tune this before using in production because you probably don't want to have wild-cards for everything
This is what worked for me:
<system.webServer>
<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>
</system.webServer>
Check if URLScan tool is installed on IIS.
When so check following section:
;
; The verbs (aka HTTP methods) listed here are those commonly
; processed by a typical IIS server.
;
; Note that these entries are effective if "UseAllowVerbs=1"
; is set in the [Options] section above.
;
GET
HEAD
POST
OPTIONS
I know this is an old post, but I just went through the exact same problem.
In my situation, I have CORS installed for both OWIN and WebAPI. The OWIN CORS middleware was intercepting the OPTIONS call long before it ever made it to the WebAPI stuff. Maybe this well help someone else in the future.
I have installed Microsoft.AspNet.WebApi.Cors & Microsoft.Owin.Cors for my oWin based WebAPI and added app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); at config like below:
public class Startup : IStartup, IAppStartup
{
public void Configuration(IAppBuilder app)
{
var config = this.GetInjectionConfiguration();
BootstrapperWebApi bootstrapperWebApi = (BootstrapperWebApi)this.GetBootstrapperWebApi(config);
bootstrapperWebApi.Initialize(true)
.EnableLogging()
.DisableWebApiDefaultExceptionHandler();
WebApiConfig.Register(config);
app.UseOwinExceptionHandler();
app.Use<LoggerMiddleware>();
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
//others stuff
}
I tried all the mentioned posts but nothing worked for me, then i shifted my ASP.Net Web API 2 service to windows server 2012 (IIS 8.5) and same service worked without any changes. So issue was specific to IIS 7.5 on windows 7 machine.
In my case I did this:
<verbs allowUnlisted="true" applyToWebDAV="true">
<remove verb="OPTIONS"/>
<add verb="OPTIONS" allowed="true"/>
</verbs>
</requestFiltering>
</security>
When I added <add verb="OPTIONS" allowed="true"/> to the web.config, the application failed to start with this error
HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Cannot add duplicate collection entry of type 'add' with unique key attribute 'verb' set to 'OPTIONS'
So I had to remove it first.
I have the same issue. The OPTIONS request return 200 OK status but it does not contain Access-Control-Allow-Origin header. The problem was our customer network policy blocking the OPTIONS verb request and response the warning message with 200 OK status. I know this is the old post but I want to share my case for anyone needed.
One more case, maybe it will save time for somebody. When I used config with HttpConfiguration.EnableCors all was working fine but when I used web.config file it was failing with CORS errors. It started work after I removed the .vs folder.
<figure>
<img src="https://i.stack.imgur.com/CbRyM.png" alt="">
<figcaption> change the OptionsVerbHangle</figcaption>
</figure>
<figure>
<img src="https://i.stack.imgur.com/wjcMV.png" alt="Minha Figura">
<figcaption>Adicione * and in the case of php use fastcgimodule</figcaption>
</figure>
<figure>
<img src="https://i.stack.imgur.com/wRwpi.png" alt="Minha Figura">
<figcaption>Mapping to folder
</figcaption>
</figure>
<figure>
<img src="https://i.stack.imgur.com/hhqJi.png" alt="Minha Figura">
<figcaption>all verbs
</figcaption>
</figure>
<figure>
<img src="https://i.stack.imgur.com/86kKX.png" alt="Minha Figura">
<figcaption>Select script
</figcaption>
</figure>
Just follow the images below to unlock the colors in IIS
enter image description here
enter image description here
enter image description here
enter image description here
enter image description here
enter image description here

return View("myHtmlPage.html") in Asp.net MVC

Masters,
In my MVC application many pages are static (HTML pages).
I've to create both .cshtml and plain HTML pages.
HTML version is also in use by another module.
When I try with return View("Mypage.html") it fails.
Is there any way to consume plain "HTML" pages for my View.
Please help.
What I did in the past was to register ".html" pages to be interpreted as dynamic pages, too. (I.e. just like ASPX).
This can be done through your "web.config" file:
....
<
system.web>
<compilation ...>
<buildProviders>
<add extension=".html"
type="System.Web.Compilation.PageBuildProvider" />
</buildProviders>
....and
....
<system.webServer>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated" />
<add name="PageHandlerFactory-Integrated-HTML" path="*.html"
verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory"
resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
this works well with IIS 7 and IIS 7.5 (and probably on above versions, too). If you are using IIS 6, you have to do it through the IIS Management Console.
Hope this helps..

Why would FederatedAuthentication.WSFederationAuthenticationModule be null in MVC Azure ACS Federated Authentication?

I'm trying to put together FederatedAuthentication with .NET 4.5, MVC 4, and active redirect using a custom server-side login page, using code from this tutorial, and from this code sample.
Redirecting to the LogOn method of my AccountController works fine, and the method looks like this:
public ActionResult LogOn()
{
HrdClient hrdClient = new HrdClient();
WSFederationAuthenticationModule fam = FederatedAuthentication.WSFederationAuthenticationModule; /*** Fails here because this is null **/
HrdRequest request = new HrdRequest(fam.Issuer, fam.Realm, context: Request.QueryString["ReturnUrl"]);
IEnumerable<HrdIdentityProvider> hrdIdentityProviders = hrdClient.GetHrdResponse(request);
ViewData["Providers"] = hrdIdentityProviders;
return View();
}
This fails because FederatedAuthentication.WSFederationAuthenticationModule is null.
Using VS 2012, I've run the new Identity and Access wizard (which seems to replace the old STS dialog). This has given me a folder of FederationMetadata, which appears correct, and several modifications to my Web.Config. In particular, the modules section looks like this:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>
And having seen SO answers 8937123 and 8926099, I've added the following as well:
<httpModules>
<add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>
And finally my nuget packages config shows Microsoft.IdentityModel, which is correctly referenced by the MVC app:
<packages>
<package id="Microsoft.IdentityModel" version="6.1.7600.16394" targetFramework="net45" />
</packages>
I've also seen this question on social.msdn, which just seems to suggest that the STS dialog does need to be run.
Can anybody explain why FederatedAuthentication.WSFederationAuthenticationModule would be null, and what I can do to stop this happening?
I managed to fix this myself, and since there are a few unanswered questions similar to this on SO, I'll leave the question up and post my own answer.
The issue is to do with upgrading the MVC application to .NET 4.5. Much of the WIF functionality remains the same (at least on the surface), but the classes have all moved to different assemblies. I fixed my problem following the migration guidelines here: http://msdn.microsoft.com/en-us/library/jj157089.aspx
The most important thing is to remove old references to the Microsoft.IdentityModel package (v 3.5.0) and make sure they are replaced by similar references to the System.IdentityModel and System.IdentityModel.Services dlls, which should be version 4.0, and come from the GAC rather than an external package.
My steps to fix were:
Clean out all the junk I'd added to Web.Config and start again with a default MVC Config file.
Remove the Microsoft.IdentityModel package and de-reference the dll
Run the Access and Identity wizard in VS 2012
Duplicate the System.IdentityModel.Services.WSFederationAuthenticationModule reference from <system.webServer><modules> in <system.web><httpModules>
Add <authentication mode="Forms"><forms loginUrl="~/Account/LogOn" /></authentication>
Compile, test, dance little jig of delight...
And this got the original WIF3.5 / MVC3 Code Sample working under.NET 4.5

Add an MVC 2 application to a Nancy site in IIS 7

In IIS 7, I have created a web site using a Nancy project. Then, I added an MVC 2 application to the site using the alias api. I am able to visit defined routes in the Nancy project perfectly. However, when I visit /api, I get the following error:
Could not load type 'Nancy.Hosting.Aspnet.NancyHttpRequestHandler'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: Could not load type 'Nancy.Hosting.Aspnet.NancyHttpRequestHandler'.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Could not load type 'Nancy.Hosting.Aspnet.NancyHttpRequestHandler'.]
System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) +11588073
System.Web.Configuration.HandlerFactoryCache.GetTypeWithAssert(String type) +47
System.Web.Configuration.HandlerFactoryCache.GetHandlerType(String type) +18
System.Web.Configuration.HandlerFactoryCache..ctor(String type) +27
System.Web.HttpApplication.GetFactory(String type) +95
System.Web.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +352
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375
It seems that the MVC 2 application is trying to use the NancyHttpRequestHandler to process the request. I say this because routes that are not defined in the Nancy application display a 404 page.
I have tried several things:
To Web.config of the MVC 2 application, I added the following to the <system.web/> block:
<httpHandlers>
<add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpHandlers>
To Web.config of Nancy application, I added the following to the <system.web/> block:
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
<remove verb="*" path="api/*" />
</httpHandlers>
I have also tried toying with the settings in the <system.webServer/> and <system.serviceModel/> blocks in both applications.
How can I get the MVC 2 application to behave properly when it is embedded in the Nancy site in IIS 7? Any guidance would be greatly appreciated.
You had the right idea -- you need to block inheritance of the NancyFx specific configuration sections to the child MVC sites.
In your root (NancyFx) site, create a <location/> tag with your normal configuration. Your NancyFx web.config structure will look something like below. (I added comments to try to keep you out of trouble if you decide to upgrade your MVC2 site to MVC3.)
<configuration>
<configSections/>
<!-- FYI... configSections cannot be moved into the location tag. If you plan
to upgrade to MVC3 and use the Razor view engine, those configSection
declarations need to live here. If you upgrade to MVC3 and use the Razor
view engine, you will need to remove the Razor configSections from the
views/web.config files any child MVC3 project. -->
<system.web /> <!-- site-wide system.web settings -->
<system.webServer /> <!-- site-wide system.webServer settings -->
<!-- Put the NancyFx specific configuration here -->
<location path="." inheritInChildApplications="false">
<!-- The inheritInChildApplications attribute is the magic sauce! :) -->
<connectionStrings />
<!-- If the connectionStrings are shared by the child site,
you could move them out to the main configuration. But they
cannot exist in both sections of this file. -->
<appSettings />
<system.web>
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</handlers>
</system.webServer>
</location>
</configuration>

Resources