I have a SPA ASP.NET WebAPI application which previously allowed anonymous access. I have now configured ASP.Net Identity for it but I cannot get the Identity related controllers and my application's other controllers to work at the same time :-( It's either one or the other!
I have added the startup class to my project:
using Test.MyProject;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;
using Owin;
using System;
using System.Configuration;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http;
[assembly: OwinStartup(typeof(Test.Client.Startup))]
namespace Test.Client
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
ConfigureOAuthTokenGeneration(app);
ConfigureWebApi(httpConfig);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
//app.UseWebApi(httpConfig); // If this line is commented out my application's controllers work. But then my Account Controller does't work. It if is included, my application's controllers don't work, whilst the Account Controller work
GlobalConfiguration.Configure(WebApiConfig.Register);
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
}
private void ConfigureWebApi(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
}
And I have added controllers for managing Users and Roles.
The statement GlobalConfiguration.Configure(WebApiConfig.Register)
was previously in the application start event in global.aspx.cs
but now moved to the startup class to have everything in the same place.
The WebApiConfig.Register
method looks like this:
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
// Web API configuration and services
string appStorageProvider = ConfigurationManager.AppSettings["StorageProvider"];
var provider =(TestComposition.StorageProvider) Enum.Parse(typeof (TestComposition.StorageProvider), appStorageProvider, true);
TestComposition.Setup(container, provider);
container.RegisterType<GeneralLogger, GeneralLogger>();
container.RegisterType<IExceptionLogger, ExceptionLogger>();
config.EnableCors();
config.DependencyResolver = new UnityResolver(container);
config.Services.Add(typeof (IExceptionLogger), container.Resolve<GeneralLogger>());
// Web API routes
config.MapHttpAttributeRoutes();
}
In my new AccountController
I have code which allows me to retrieve the ApplicationUserManager
from the OwinContext
set up in the Startup class.
protected ApplicationUserManager AppUserManager
{
get
{
return _AppUserManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
}
With app.UseWebApi(httpConfig)
commented out as shown above my application works as it used to. But if I invoke any action on my new AccountController
I get this:
Request.GetOwinContext() error CS1061: 'HttpRequestMessage' does not contain a definition for 'GetOwinContext' and no extension method 'GetOwinContext' accepting a first argument of type 'HttpRequestMessage' could be found (are you missing a using directive or an assembly reference?)
If I comment in the app.UseWebApi(httpConfig)
statement the AccountController
works but then my other controllers don't work. Here I get errors like these:
{ "message": "An error has occurred.", "exceptionMessage": "An error occurred when trying to create a controller of type 'TestController'. Make sure that the controller has a parameterless public constructor.", "exceptionType": "System.InvalidOperationException", "stackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()", "innerException": { "message": "An error has occurred.", "exceptionMessage": "Type 'MyProject.Api.TestController' does not have a default constructor", "exceptionType": "System.ArgumentException", "stackTrace": " at System.Linq.Expressions.Expression.New(Type type)\r\n at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)" } }
Any idea what is going on here?