Create an User in a Console .NET Core Application - asp.net

I have a ASP.NET Core 1.0 Solution with 3 projects (Web, Console Application, DataAccessLayer).
I use ASP.NET Core Identity and Entity Framework Core (SQL Server - Code First).
In my Console Application (Used for background tasks), I want to create users, but how I can have access to UserManager object in a Console Application (Or in a .NET Core Class Library) ?
In a controller class, it's easy with Dependency Injection :
public class AccountController : Controller {
private readonly UserManager<ApplicationUser> _userManager;
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
}
//...
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
//...
}
How I can do the equivalent in a Console Core Application ?

Thanks to Tseng's answer I ended up with this code. Just in case if someone would need:
public class Program
{
private interface IUserCreationService
{
Task CreateUser();
}
public static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddDbContext<ApplicationDbContext>(
options =>
{
options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=my-app-db;Trusted_Connection=True;MultipleActiveResultSets=true");
});
// Authentification
services.AddIdentity<ApplicationUser, IdentityRole>(opt =>
{
// Configure identity options
opt.Password.RequireDigit = false;
opt.Password.RequireLowercase = false;
opt.Password.RequireUppercase = false;
opt.Password.RequireNonAlphanumeric = false;
opt.Password.RequiredLength = 6;
opt.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddScoped<IUserCreationService, UserCreationService>();
// Build the IoC from the service collection
var provider = services.BuildServiceProvider();
var userService = provider.GetService<IUserCreationService>();
userService.CreateUser().GetAwaiter().GetResult();
Console.ReadKey();
}
private class UserCreationService : IUserCreationService
{
private readonly UserManager<ApplicationUser> userManager;
public UserCreationService(UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
public async Task CreateUser()
{
var user = new ApplicationUser { UserName = "TestUser", Email = "test#example.com" };
var result = await this.userManager.CreateAsync(user, "123456");
if (result.Succeeded == false)
{
foreach (var error in result.Errors)
{
Console.WriteLine(error.Description);
}
}
else
{
Console.WriteLine("Done.");
}
}
}
}

In my Console Application (Used for background tasks), I want to create users, but how I can have access to UserManager object in a Console Application (Or in a .NET Core Class Library) ?
Same as you do it in ASP.NET Core. You just need to bootstrap it yourself. Inside your Main (which is the console applications composition root - the earliest point where you can set up your object graph).
Here you create a ServiceCollection instance, register the services and build the container, then resolve your app entry point. From there, anything else goes via DI.
public static int Main(string[] args)
{
var services = new ServiceCollection();
// You can use the same `AddXxx` methods you did in ASP.NET Core
services.AddIdentity();
// Or register manually
services.AddTransient<IMyService,MyService();
services.AddScoped<IUserCreationService,UserCreationService>();
...
// build the IoC from the service collection
var provider = services.BuildServiceProvider();
var userService = provider.GetService<IUserCreationService>();
// we can't await async in Main method, so here this is okay
userService.CreateUser().GetAwaiter().GetResult();
}
public class UserCreationService : IUserCreationService
{
public UserManager<ApplicationUser> userManager;
public UserCreationService(UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
public async Task CreateUser()
{
var user = new ApplicationUser { UserName = "TestUser", Email = "test#example.com" };
var result = await _userManager.CreateAsync(user, model.Password);
}
}
In practice the first class you resolve wouldn't be your UserCreationService but some MainApplication class, which is the core of your application and responsible for keeping the application alive as long as the operation happens, i.e. if its a background worker you run some kind of host (Azure Web Job Host etc.) which keeps the application running so it can receive events from outside (via some message bus) and on each event starts a specific handler or action, which in turn resolves other services etc.

I know this answer is late, but other people might benefit.
You are seriously overcomplicating things using services etc.
You can just do:
var userStore = new UserStore<ApplicationUser>(new ApplicationDbContext());
var manager = new ApplicationUserManager(userStore);
var result = await manager.Create(user, password);
If you still want all the password validation functionality just add it to the constructor of ApplicationUserManager

Related

Injecting dependency from a Class Library project to Xamarin Forms

I have got a brand new Xamarin Form project that requires access to an existing class in a class library project (net standards 2.1).
I would like Xamarin forms to use ClientQueries class from the other project.
ClientQueries has got a HttpClientFactory property using dependency injection and several methods to call an API and it looks something like this:
public class ClientQueries
{
private readonly ClientFactory _ClientFactory;
public TSClientQueries(ClientFactory ClientFactory)
{
_ClientFactory = ClientFactory ?? throw new ArgumentNullException(nameof(ClientFactory));
}
public async Task<Result<Token>> GetToken(CancellationToken cancellationToken, string username, string password)
{
var client = _ClientFactory.Create();
var response = await client.GetToken(cancellationToken, username, password).ConfigureAwait(true);
return response;
}
}
I follow this sample which explains we can make use of Microsoft.Extensions for HttpClientFactory and adding singleton services. This is the link: ASP.NET Core's Dependency Injection into Xamarin Apps with HostBuilder
I tried this StartUp class in Xamarin Forms project which is similar to the asp.net core project which uses the same Class Library with ClientQueries:
public class Startup
{
public static IServiceProvider ServiceProvider { get; set; }
public static void Init()
{
var a = Assembly.GetExecutingAssembly();
using var stream = a.GetManifestResourceStream("App1.appsettings.json");
var host = new HostBuilder()
.ConfigureHostConfiguration(c =>
{
c.AddCommandLine(new string[] { $"ContentRoot={FileSystem.AppDataDirectory}" });
c.AddJsonStream(stream);
})
.ConfigureServices((c, x) => ConfigureServices(c, x))
.ConfigureLogging(l => l.AddConsole(o =>
{
//o.DisableColors = true;
}))
.Build();
ServiceProvider = host.Services;
}
static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
#region "api service"
services.AddSingleton<ClientQueries>();
services.AddHttpClient<Client>("HttpClient",
x => { x.BaseAddress = new Uri(ctx.Configuration["APIConfiguration:BaseAddress"]); }
).AddPolicyHandler(GetRetryPolicy());
services.AddSingleton<ClientFactory>();
#endregion
}
Is it possible to inject ClientQueries in ViewModels like the way I used to do it in asp.net core controllers?
public class AccountController : Controller
{
private readonly ClientQueries _ClientQueries;
public AccountController(ClientQueries ClientQueries)
{
_tsClientQueries = tsClientQueries;
}
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var t = await _ClientQueries.GetToken(CancellationToken.None, model.UserName, model.Password);
[coded abbreviated for simplicity]
Or Has Prism got anything functionality which will allow me to use depedency injection for HttpClientFactory in ClientQueries and Use ClienQueries as a singleton in ViewModels in Xamarin?
I tried DependencyServices and I did not get it right.
Thanks.

I'm new to .NET Core 2.1 MVC and I'm having trouble understanding how a few things work

I'm currently following a .Net Core Angular 8 tutorial in Udemy. I'm able do get/post requests in Postman and I can also see what I've posted in a .db file using sqlite as my database and viewing the data through Db Browser. Everything seems to be working great but is all for nothing if I can't comprehend what's going on in some areas of the application. I would really appreciate it if someone could help me answer a few questions.
My entire project is in GitHub: https://github.com/cjtejada/ASP.NetCoreAngular8/tree/master/DatingApp.API
Problem 1: I have the following the following controller:
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly IAuthRepository _repo;
private readonly IConfiguration _config;
public AuthController(IAuthRepository repo, IConfiguration config)
{
_repo = repo;
_config = config;
}
[HttpPost("register")]
public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
{
// validate request
userForRegisterDto.Username = userForRegisterDto.Username.ToLower();
if (await _repo.UserExists(userForRegisterDto.Username))
return BadRequest("User already exists");
var userToCreate = new User
{
Username = userForRegisterDto.Username
};
var createdUser = await _repo.Register(userToCreate, userForRegisterDto.Password);
return StatusCode(201);
}
}
I know that when the client makes a request to register, the register() method will be called and the Username that gets passed in will set the Username from DTO userForRegisterDto. After this then we call method UserExists() to check if the user exists in our database.
Question 1:
How is _repo aware of the logic in method UserExists() when it is only using the interface IAuthRepository? I know that IAuthRepository and class AuthRepository are somehow linked but I don't see anywhere in the app where Constructor DI is happening. My suspicion is that it has something to do with this line in startup.cs under the ConfigureServices method :
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors();
services.AddScoped<IAuthRepository, AuthRepository>(); //<---- This Line
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
}
After these two are "linked up", then the UserExists() method can be accessed through the AuthRepository class:
public class AuthRepository : IAuthRepository
{
private readonly DataContext _context;
public AuthRepository(DataContext context)
{
_context = context;
}
public async Task<User> Login(string username, string password)
{
}
private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
{
}
public async Task<User> Register(User user, string password)
{
byte[] passwordHash, passwordSalt;
CreatePasswordHash(password, out passwordHash, out passwordSalt);
user.PasswordHash = passwordHash;
user.PasswordSalt = passwordSalt;
await _context.Users.AddAsync(user);
await _context.SaveChangesAsync();
return user;
}
private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
{
}
public async Task<bool> UserExists(string username)
{
if (await _context.Users.AnyAsync(x => x.Username == username))
return true;
return false;
}
}
I've been reading about the AddScoped method and what it does but this is not clear to me that this is the case. Any clarification as to how this works would be great.
Problem 2:
This one is more or less the same. If we keep following the path of the request we will hit the register() method in the AuthRepository class.
Question 2:
How does this class have access to the properties of DataContext _context when I also can't spot any instances of constructor DI anywhere?
Here are the rest of my project files if needed:
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors();
services.AddScoped<IAuthRepository, AuthRepository>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseAuthentication();
app.UseMvc();
}
}
DataContext.cs
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options) : base (options){}
public DbSet<Value> Values { get; set; }
public DbSet<User> Users { get; set; }
}
Any clarifications and suggestions are greatly appreciated. Thanks, all.
You are correct. The line services.AddScoped<IAuthRepository, AuthRepository>(); simply instructs the ASP.NET Core service container to substitute an instance of concrete class AuthRepository wherever it sees a reference to IAuthRepository at runtime.
The various Add* methods all do the same thing under the hood regarding registering the mapping of interfaces => classes, the key difference is the scope of the created class, i.e. how long it persists for:
AddScoped classes will be created at the beginning of every request to the server, and destroyed at the end of every request. In other words, every request results in a new instance of that class being created.
AddSingleton classes are created when your ASP.NET Core application starts up, and are destroyed when it shuts down. In other words, only a single instance of that class exists within your application.
AddTransient classes are recreated whenever they are requested. In other words, if a page on your site used the same service transient twice, there would be two instances created. (Contrast this with a scoped service, where only a single instance would be created, as each page is a single request.)
A fuller explanation, including examples: https://stackoverflow.com/a/38139500/70345
In order to fulfill (1) by creating an instance of your class AuthRepository, the service container needs to call that class's constructor. The container inspects your class to find the first public constructor and retrieves any arguments to that constructor, in this case an instance of the DataContext class. The container then searches its internal class mappings for that class and, because you have registered that mapping via services.AddDbContext<DataContext>(...), is able to construct and return the class instance. Thus it's able to pass that instance to AuthRepository, so AuthRepository is constructed successfully.
The AddDbContext method is simply a wrapper around AddScoped, that performs some additional scaffolding to allow Entity Framework DbContexts to work correctly.
For the official explanation, refer to Microsoft's official page on DI and IoC.
Question 1 - You've right this line in Startup.cs provide creating a new object AuthRepository. For this example you must to know that DI container creates an AuthRepository object for you based on the interface and his own implementation and you only need to pass an interface in properly constructor. AddScope() is related with lifetime of created objects. When you register object by method AddScope() then the object will be created for a single request and after the request, the object will be disposed.
Question 2 - Your dbContext is registered in DI container. AddDbContext() is a specific extension method provided to registration of entity framework dbContextes. This line of code registers your dbContext with connection strings got from the appSetting.json file.
services.AddDbContext<DataContext>(x =>
x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
This DbContext is injected into the constructor of the AuthRepository class and when you use this class DI container created DbContext instance for you.
private readonly DataContext _context;
public AuthRepository(DataContext context)
{
_context = context;
}

ASP.NET MVC 5 with NUnit and Moq; how to mock RoleManager so it is possible to setup it's extension methods?

I have ASP.NET MVC 5 (.NET Framework) app with Entity Framework 6.2.
I'm using NUnit and Moq frameworks for testing.
I need to test if roleResult.Succeeded is true when RoleExists() extension(static) method returns false for "User" role.
HomeController.cs :
private ApplicationDbContext _db;
private RoleManager<IdentityRole> _roleManager;
private ApplicationUserManager _userManager;
// Hard Entity Framework dependency (working application)
public HomeController()
{
_db = new ApplicationDbContext();
_roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(_db));
_userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(_db));
if (!_roleManager.RoleExists("User"))
{
IdentityResult roleResult = _roleManager.Create(new IdentityRole("User"));
}
}
// Dependency injection only for testing
public HomeController(ApplicationDbContext context, ApplicationUserManager userManager, RoleManager<IdentityRole> roleManager, string role) // DI for testing
{
_db = context;
_roleManager = roleManager;
_userManager = userManager;
if (!_roleManager.RoleExists(role))
{
IdentityResult roleResult = _roleManager.Create(new IdentityRole(role));
}
}
HomeTest.cs :
[Test]
public void HomeController_RoleDoesNotExist_AddRole()
{
var mockContext = new Mock<ApplicationDbContext>();
var mockUserManager = new Mock<ApplicationUserManager>();
var mockRoleManager = new Mock<RoleManager<IdentityRole>>();
mockRoleManager.Setup(x => x.RoleExists("User")).Returns(false); // Moq says: nope :<
var homeController = new HomeController(mockContext.Object, mockUserManager.Object, mockRoleManager.Object, "User");
// Some Assert that I really don't know to deal with.
}
First: I don't know how implement testing code responsible for getting roleResult.Succeeded value.
Second: Moq cannot setup static methods and I don't know how to deal with it in my situation. I'll probably need to replace private properties in my HomeController class with some new interfaces but then my Hard Entity Framework dependency will stop working because of for example: _db = new ApplicationDbContext() cannot be converted to IMyNewAppDbContext.
Thanks for help.

How to avoid code redundance in ASP.Net Core?

I implemented SendGrid in my application, and inside the Account controller I have a method called Register. The method Register allow to the user to signup on the site, inside this method I have the following code:
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new
{
userId = user.Id,
token = code
}, protocol: Request.Scheme);
await _emailSender.SendEmailAsync(user.Email, _localizer["ConfirmYourEmail"], _localizer["ConfirmAccountTemplate", callbackUrl]);
as you can see I generate a confirmation code, and then I created a callBackUrl that the user can find inside the email for confirm the email address. At the end, I call SendEmailAsync which is essentially an implementation of the interface method of Microsoft.AspNetCore.Identity.UI.Services.
Now the main problem is the following: I need to use the same code inside a Repository class, so not inside a Controller, is there a place to store this type of code without create redundance?
PS: I'm sorry if this question seems stupid, but I'm actually a newbie of ASP.NET Core and I want learn to how to create a good project structure.
Thanks in advance for any help.
I need to reuse the method to create the code and send the email
This is a quick mark up I didn't test if this works. You want to make something of the following, and use this in Dependency Injection (DI). You might need to add IUrlHelper and IHttpContextAccessor
public class SomeClass : ISomeClass
{
private HttpContext _ctx;
private IUrlHelper _url;
private IConfiguration _localizer;
private IEmailSender _emailSender;
private UserManager<ApplicationUser> _userManager;
public SomeClass(
IUrlHelper url,
IHttpContextAccessor ctx,
IConfiguration config,
IEmailSender emailSender,
UserManager<ApplicationUser> userManager)
{
_ctx = ctx.HttpContext;
_url = url;
_localizer = config;
_emailSender = emailSender;
_userManager = userManager;
}
public async Task SendEmailWithCode(string email)
{
var user = await _userManager.FindByEmailAsync(email);
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
var callbackUrl = _url.Action(nameof(ResetPassword), "Account", new { userId = user.Id, code }, protocol: _ctx.Request.Scheme);
await _emailSender.SendEmailAsync(user.Email, _localizer["ConfirmYourEmail"], _localizer["ConfirmAccountTemplate"], callbackUrl);
}
}

Why is the identity not loaded when resolving WebApi but is when resolving Mvc controllers

I am using Autofac for an Inversion of Control container which is configured like this
public void Configuration(IAppBuilder app) {
configureIoC(app);
configureAuth(app);
}
void configureIoC(IAppBuilder app) {
var b = new ContainerBuilder();
//...
b.Register(c => HttpContext.Current?.User?.Identity
?? new NullIdentity()).InstancePerLifetimeScope();
var container = b.Build();
app.UseAutofacMiddleware(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
I believe the fact that this is Autofac versus some other container is probably irrelevant to what I'm seing. They key line here is the one configuring any dependency on IIdentity to be plucked from HttpContext.Current.
I use it like this so that I can have stub-able access to the current user anywhere I want.
public interface ICurrentUser {
Task<AppUser> Get();
}
public class CurrentUserProvider : ICurrentUser {
public async Task<AppUser> Get() => await users.FindByNameAsync(currentLogin.GetUserId());
public CurrentUserProvider(AppUserManager users, IIdentity currentLogin) {
this.users = users;
this.currentLogin = currentLogin;
}
}
I've used this pattern on past projects and it works fine. I'm currently applying it to an existing project and seeing a very strange thing.
When an Asp.net Mvc controller depends on ICurrentUser everything works fine
When a WebApi controller gets an instance of ICurrentUser the Get operation fails since the instance of IIdentity has not been parsed from the cookie and does not yet have Claims loaded into it (AuthenticationType == null)! Oddly, if I pause the debugger after the WebApi controller is instantiated I can hit HttpContext.Current.User.Identity and see that AuthenticationType == "Cookie" and all claims are there.
What this leads me to conclude is that somehow things are happening in the following order
If this is a web api route, the Web Api controller creates an instance
Asp.Net Identity fills out the current HttpContext Identity
If this is an mvc route, the mvc controller creates an instance
Any actions are executed
This of course makes no sense at all!
So the questions are as follows
Is my inference of the order of things in the pipeline correct?
How can I control it to work properly? Why would this have worked on other projects but be causing problems here? Am I wiring something up in the wrong order?
Please don't suggest that I create an IdentityProvider to late-resolve IIdentity. I understand how I can fix the issue, what I don't understand is why this is happening to begin with and how to control the pipeline order of things.
I modified your code just a little, since I don't have NullIdentity() and your CurrentUserProvider wasn't compiling here.
I'm installed these packages:
Autofac
Autofac.Owin
Autofac.Owin
Autofac.Mvc5
Autofac.Mvc5.Owin
Autofac.WebApi2
Autofac.WebApi2.Owin
My Startup.cs looks like this:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
configureIoC(app);
ConfigureAuth(app);
}
void configureIoC(IAppBuilder app) {
var b = new ContainerBuilder();
//...
b.RegisterType<CurrentUserProvider>().As <ICurrentUser>().InstancePerLifetimeScope();
b.Register(c => HttpContext.Current.User.Identity).InstancePerLifetimeScope();
b.RegisterControllers(typeof(MvcApplication).Assembly);
b.RegisterApiControllers(typeof(MvcApplication).Assembly);
var x = new ApplicationDbContext();
b.Register<ApplicationDbContext>(c => x).InstancePerLifetimeScope();
b.Register<UserStore<ApplicationUser>>(c => new UserStore<ApplicationUser>(x)).AsImplementedInterfaces().InstancePerLifetimeScope();
b.RegisterType<ApplicationUserManager>().InstancePerLifetimeScope();
b.RegisterType<ApplicationSignInManager>().InstancePerLifetimeScope();
var container = b.Build();
app.UseAutofacMiddleware(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
Your ICurrentUser stuff:
public interface ICurrentUser
{
Task <ApplicationUser> Get();
}
public class CurrentUserProvider : ICurrentUser
{
private ApplicationUserManager users;
private IIdentity currentLogin;
public async Task<ApplicationUser> Get()
{
return await users.FindByNameAsync(currentLogin.GetUserId());
}
public CurrentUserProvider(ApplicationUserManager users, IIdentity currentLogin)
{
this.users = users;
this.currentLogin = currentLogin;
}
}
Therefore Global.asax:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
My HomeController which is quite simple:
public class HomeController : Controller
{
private ICurrentUser current;
public HomeController(ICurrentUser current)
{
this.current = current;
}
public ActionResult Index()
{
var user = current.Get();
if (user == null)
throw new Exception("user is null");
return View();
}
}
...and finally a simple ApiController, which I access by typing localhost/api/TestApi/5:
public class TestApiController : ApiController
{
private ICurrentUser current;
public TestApiController(ICurrentUser current)
{
this.current = current;
}
public string Get(int id)
{
var user = current.Get();
if (user == null)
throw new Exception("user is null");
return "";
}
}
If I just start the project (without even logging in), I receive a GenericIdentity object to support IIdentity interface, look at this:
And when I step in (F11) in the Get() method, the IIdentity is properly set with that GenericIdentity, because actually there is no one Logged in the application. That's why I think you don't actually need that NullableIdentity.
Try comparing your code with mine and fix yours so we can see if it works, then eventually you'll find out what was the real cause of the problem, rather than just fixing it (we developers like to know why something just got working).

Resources