how to return view from custom middleware? - middleware

My goal is intercept 404 status code using middleware and return custom view (interrupt execution).
I tried some examples. And, only await context.Response.WriteAsync("test 404 response error"); works. But this is not I need.
How to achieve this?
My next example does not work (I mean I got blank page or default Chrome not found page):
public class CustomError404Middleware
{
private readonly RequestDelegate _next;
public CustomError404Middleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await _next(context);
if (context.Response.StatusCode == 404 && !context.Response.HasStarted)
{
//Re-execute the request so the user gets the error page
var originalPath = context.Request.Path.Value;
context.Items[nameof(Defaults.ORIGINAL_PATH)] = originalPath;
context.Request.Path = "Error/404";
// context.Request.Path = "/Error/404";
await _next(context);
}
}
}
Configuration:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// app.UseStatusCodePages();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<RequestLoggerMiddleware>();
app.UseMiddleware<CustomError404Middleware>();
.............. skipped (Rollbar, CORS) ..............
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "dashboard",
pattern: "{controller=Home}/{action=Index}");
endpoints.MapRazorPages();
endpoints.MapMetrics();
});
Controller and view:
[AllowAnonymous]
public class ErrorController : Controller
{
[ActionName("404")]
public IActionResult PageNotFound()
{
ViewData[nameof(Defaults.ORIGINAL_PATH)] = "unknown";
if (HttpContext.Items.ContainsKey(nameof(Defaults.ORIGINAL_PATH)))
{
ViewData[nameof(Defaults.ORIGINAL_PATH)] = HttpContext.Items[Defaults.ORIGINAL_PATH] as string;
}
return View();
}
}
#ViewData[nameof(Defaults.ORIGINAL_PATH)]
<div>
<p>
test
</p>
</div>

To achieve a similar end, I created a helper method in my middleware class
private Task GetViewResultTask(HttpContext context, string viewName)
{
var viewResult = new ViewResult()
{
ViewName = viewName
};
var executor = context.RequestServices.GetRequiredService<IActionResultExecutor<ViewResult>>();
var routeData = context.GetRouteData() ?? new Microsoft.AspNetCore.Routing.RouteData();
var actionContext = new ActionContext(context, routeData,
new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor());
return executor.ExecuteAsync(actionContext, viewResult);
}
and then from the middleware where I actually wanted to return the view (after some conditional logic maybe, or doing some other things), I would
await GetViewResultTask(context, "~/Views/Home/NotRegistered.cshtml");
return;

At the end after all tries I did workaround with built-in "re-execute"
//startup.cs
app.UseStatusCodePagesWithReExecute("/Error/{0}");
Controller and view:
//controller
[HttpGet]
[ActionName("404")]
public async Task<IActionResult> Error404()
{
return await Task.Run(() => View(ErrorModel(HttpContext)));
}
private ErrorViewModel ErrorModel(HttpContext context)
{
return new ErrorViewModel(OriginalUrl(context), RequestId(context));
}
private string OriginalUrl(HttpContext context)
{
var feature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
return feature?.OriginalPath;
}
private string RequestId(HttpContext context)
{
return Activity.Current?.Id ?? context.TraceIdentifier;
}
//view just as a sample
<div class="h-100 mt-4">
<div class="d-flex justify-content-center align-items-center h-100">
<div class="text-center">
<p class="font-weight-bold" style="font-size:10rem">404</p>
<br />
<p class="font-weight-bold" style="font-size:3rem">Requested page not found</p>
<br />
<p class="font-weight-bold">ID: #Model.RequestId</p>
<p class="font-weight-bold">URL: #Model.OriginalUrl</p>
</div>
</div>
</div>

Related

This Page isn't working Localhost redirected too many times MVC

Program.cs File with Cookie authentication:
builder.Services.AddAuthentication("CookieAuthentication").AddCookie("CookieAuthentication", options =>
{
options.LoginPath = "/<Login/LoginView";
options.AccessDeniedPath = "/Login/AccessDenied";
});
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=Signup}/{id?}");
app.Run();
Login Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult LoginView(string username, string password)
{
if (!ModelState.IsValid)
{
//Error code here
}
if (!UserExists(username, password))//Check if user exists in Database
{
//Error code here
}
TempData["Username"] = username;
return RedirectToAction("Index", "Home");
//I used breakpoint here and this code runs but doesn't work properly.
}
I have also used the [Authorize] attribute on Home Controller to prevent users from accessing it without login.Login/LoginView is the Login rage Path.
This Page isn't working Localhost redirected too many times MVC
For your current scenario,be sure add the [AllowAnonymous] on your Index action in the HomeController. And your LoginPath is /Home/Index, it is no need to be authorized.
[Authorize]
public class HomeController : Controller
{
[AllowAnonymous]
public async Task<IActionResult> Index()
{
//do your stuff...
return View();
}
//....
}
Update:
Cookie authentication to login
Program.cs:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = "/Login/LoginView";
options.AccessDeniedPath = "/Login/AccessDenied";
});
var app = builder. Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication(); //be sure add authentication and authorization middleware.....
app.UseAuthorization();
//...
How to sigh in the user:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LoginView(string username, string password)
{
if (!ModelState.IsValid)
{
//Error code here
}
if (!UserExists(username, password))//Check if user exists in Database
{
//Error code here
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier,username) //add the claims you want...
};
//authProperties you can choose any option you want, below is a sample...
var authProperties = new AuthenticationProperties
{
//IssuedUtc = DateTimeOffset.UtcNow,
//ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),
//IsPersistent = false
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
TempData["Username"] = username;
return RedirectToAction("Index", "Home");
}

Exception occurred while processing message. System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden

I am following this tutorial which secures my Blazor WebAssembly Apps with Auth2.com and I am using command line to run the program. I could completed all the steps successfully and I could the Blazor app. But for the last step, I got this error from the command line
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[3]
Exception occurred while processing message. System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. ---> System.ArgumentException: IDX20108: The address specified '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' is not valid as per HTTPS scheme. Please specify an https address for security reasons. If you want to test with http address, set the RequireHttps property on IDocumentRetriever to false. (Parameter 'address')
and in my browser console, I get error below:
This is QuizViewer.razor which consume the API
#page "/quizViewer"
#attribute [Authorize]
#using QuizManagerClientHosted.Shared
#using System.Net.Http.Json
#using Microsoft.AspNetCore.Components.WebAssembly.Authentication
#using System.Net.Http.Headers
#inject HttpClient Http
#inject IAccessTokenProvider TokenProvider
<h1>Take your quiz!</h1>
<p>Your current score is #currentScore</p>
#if (quiz == null)
{
<p><em>Loading...</em></p>
}
else
{
int quizIndex = 0;
#foreach (var quizItem in quiz)
{
<section>
<h3>#quizItem.Question</h3>
<div class="form-check">
#{
int choiceIndex = 0;
quizScores.Add(0);
}
#foreach (var choice in quizItem.Choices)
{
int currentQuizIndex = quizIndex;
<input class="form-check-input" type="radio" name="#quizIndex" value="#choiceIndex" #onchange="#((eventArgs) => UpdateScore(Convert.ToInt32(eventArgs.Value), currentQuizIndex))" />#choice<br>
choiceIndex++;
}
</div>
</section>
quizIndex++;
}
}
#code {
List<QuizItem> quiz;
List<int> quizScores = new List<int>();
int currentScore = 0;
protected override async Task OnInitializedAsync()
{
using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, "quiz"))
{
var tokenResult = await TokenProvider.RequestAccessToken();
if (tokenResult.TryGetToken(out var token))
{
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token.Value);
var response = await Http.SendAsync(requestMessage);
quiz = await response.Content.ReadFromJsonAsync<List<QuizItem>>();
}
}
}
void UpdateScore(int chosenAnswerIndex, int quizIndex)
{
var quizItem = quiz[quizIndex];
if (chosenAnswerIndex == quizItem.AnswerIndex)
{
quizScores[quizIndex] = quizItem.Score;
}
else
{
quizScores[quizIndex] = 0;
}
currentScore = quizScores.Sum();
}
}
and this is the API controller
using QuizManagerClientHosted.Shared;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
namespace QuizManagerClientHosted.Server.Controllers
{
[ApiController]
[Route("[controller]")]
[Authorize]
public class QuizController : ControllerBase
{
private static readonly List<QuizItem> Quiz = new List<QuizItem> {
new QuizItem
{
Question = "Which of the following is the name of a Leonardo da Vinci's masterpiece?",
Choices = new List<string> {"Sunflowers", "Mona Lisa", "The Kiss"},
AnswerIndex = 1,
Score = 3
},
new QuizItem
{
Question = "Which of the following novels was written by Miguel de Cervantes?",
Choices = new List<string> {"The Ingenious Gentleman Don Quixote of La Mancia", "The Life of Gargantua and of Pantagruel", "One Hundred Years of Solitude"},
AnswerIndex = 0,
Score = 5
}
};
[HttpGet]
public List<QuizItem> Get()
{
return Quiz;
}
}
}
and Server startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace QuizManagerClientHosted.Server
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = Configuration["Auth0:Authority"];
options.Audience = Configuration["Auth0:ApiIdentifier"];
});
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}
}
How do I fix this? Which part I configure wrongly?
Each account in Auth0 has a discovery endpoint and you can find it by going to Settings for your Auth0 application and then under Advanced settings you will find the Endpoints tab.
Under there you will find your OpenID Configuration URL.
If you're following the Blazor WASM tutorial and you run into this error what most likely happened is you added https:// to the Domain in Server/appsettings.json
{ "Auth0": { "Domain": "https://something.auth0.com" } }
The example code for the Server/Program.cs uses string interpolation to add the https://
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, c =>
{
// HERE
c.Authority = $"https://{builder.Configuration["Auth0:Domain"]}";
c.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidAudience = builder.Configuration["Auth0:Audience"],
// AND HERE
ValidIssuer = $"https://{builder.Configuration["Auth0:Domain"]}"
};
});
So either remove https:// from the Server/appsettings.json or remove it from Server/Program.cs

Why does authorization fails when I publish on IIS in aspnet core?

I have used aspnet core identity for login functionality in my webapp. I have published my webapp on IIS. It loads perfectly but when I enter username and password and navigate to action methods bearing authorize attribute the applications fails. But renaming the action methods with AllowAnonymous attribute solves my issue!!
Note: The application runs perfect with authorize attribute when I debug it locally(localhost)
how could I fix this?
startup.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OnlineExam.Models.LoginModel;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Authorization;
using OnlineExam.Models.CandidateLogin;
namespace OnlineExam
{
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.AddControllersWithViews();
services.AddEntityFrameworkSqlServer();
services.AddIdentity<OnlineExam.Models.UserAccountModel.ApplicationUser, IdentityRole>(options =>
{
options.User.AllowedUserNameCharacters = default;
options.User.RequireUniqueEmail = false;
})
.AddEntityFrameworkStores<Models.UserAccountModel.OnlineExamDBContext>();
//services.AddMvc();
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddDbContext<OnlineExamDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LoginConnection")));
services.AddDbContext<OnlineExam.Models.AdminQuestionModel.OnlineExamDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LoginConnection")));
services.AddDbContext<CandidateLoginDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LoginConnection")));
services.AddDbContext<OnlineExam.Models.CandidateExam.CandidateExamDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LoginConnection")));
services.AddScoped<OnlineExam.Models.UserAccountModel.OnlineExamDBContext>();
//services.AddScoped<OnlineExam.Controllers.AdminQuestionController>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//if (env.IsDevelopment())
//{
// app.UseDeveloperExceptionPage();
//}
//else
//{
// app.UseExceptionHandler("/Home/Error");
// // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
// app.UseHsts();
//}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using OnlineExam.Models.UserAccountModel;
using System.Web;
using Newtonsoft.Json;
using System.Text.Json;
namespace OnlineExam.Controllers
{
[AllowAnonymous]
public class UserAccountsController : Controller
{
private readonly OnlineExamDBContext _context;
private readonly UserManager<OnlineExam.Models.UserAccountModel.ApplicationUser> _userManager;
private readonly SignInManager<OnlineExam.Models.UserAccountModel.ApplicationUser> _signInManager;
List<ApplicationUser> userList = new List<ApplicationUser>();
public UserAccountsController(OnlineExamDBContext context, UserManager<OnlineExam.Models.UserAccountModel.ApplicationUser> userManager, SignInManager<OnlineExam.Models.UserAccountModel.ApplicationUser> signInManager)
{
_context = context;
_userManager = userManager;
_signInManager = signInManager;
}
// GET: UserAccounts
public async Task<IActionResult> Index()
{
return View(await _context.ApplicationUser.ToListAsync());
}
// GET: UserAccounts/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var userAccount = await _context.ApplicationUser
.FirstOrDefaultAsync(m => m.UserAccountId == id);
if (userAccount == null)
{
return NotFound();
}
return View(userAccount);
}
// GET: UserAccounts/Create
[HttpGet]
public IActionResult Create()
{
var viewmodel = new ApplicationUser();
return View(viewmodel);
}
// POST: UserAccounts/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ApplicationUser userModel)
{
if (ModelState.IsValid)
{
bool userCheck = IsUserExists(userModel.UserName);
if (userCheck == false)
{
var user = new OnlineExam.Models.UserAccountModel.ApplicationUser();
user = userModel;
var result = await _userManager.CreateAsync(user, userModel.UserPassword);
if (result.Succeeded)
{
return Logout();
}
else
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
else
{
ModelState.AddModelError("","Username already exist");
}
}
return View(userModel);
}
// GET: UserAccounts/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var userAccount = await _context.ApplicationUser.FindAsync(id);
if (userAccount == null)
{
return NotFound();
}
return View(userAccount);
}
// POST: UserAccounts/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("UserAccountId,UserName,UserPassword,UserFullName,UserGender,UserPriviledge,UserDesignation,UserDepartment,UserMailId,UserAddress,UserMobileNo,UserPhoto,UserQualification")] UserAccount userAccount)
{
if (id != userAccount.UserAccountId)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(userAccount);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UserAccountExists(userAccount.UserAccountId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(userAccount);
}
// GET: UserAccounts/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var userAccount = await _context.ApplicationUser
.FirstOrDefaultAsync(m => m.UserAccountId == id);
if (userAccount == null)
{
return NotFound();
}
return View(userAccount);
}
// POST: UserAccounts/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var userAccount = await _context.ApplicationUser.FindAsync(id);
_context.ApplicationUser.Remove(userAccount);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool UserAccountExists(int id)
{
return _context.ApplicationUser.Any(e => e.UserAccountId == id);
}
[AllowAnonymous]
[HttpGet]
public IActionResult Login()
{
return View();
}
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login(ApplicationUser login)
{
///var user = new OnlineExam.Models.UserAccountModel.ApplicationUser { UserName = login.UserName };
//TempData["user"] = user;
var result = await _signInManager.PasswordSignInAsync(login.UserName, login.UserPassword, true, false);
if (result.Succeeded)
{
var userData = from x in _context.ApplicationUser.Where(x => x.UserName == login.UserName).ToList()
select new { x.UserFullName, x.Email, x.UserAddress ,x.UserName
,x.UserPhoto ,x.UserMobileNo,x.UserGender,x.UserQualification,
x.UserDepartment,x.UserDesignation,x.UserPriviledge,x.UserAccountId};
//List<ApplicationUser> userList = new List<ApplicationUser>();
foreach (var item in userData)
{
userList.Add(new ApplicationUser
{ UserFullName =item.UserFullName, UserAccountId= item.UserAccountId,UserName=item.UserName,
Email=item.Email,UserDepartment=item.UserDepartment,UserGender=item.UserGender,
UserPriviledge=item.UserPriviledge, UserPhoto=item.UserPhoto, UserAddress=item.UserAddress
});
//userList.Add(new ApplicationUserReplica { UserAccountId = item.UserAccountId });
}
//List<ApplicationUserReplica> userList= new List<ApplicationUserReplica>();
//userList.Add(new ApplicationUserReplica { UserFullName = userData.Select(x => x.UserFullName).ToString()});
// userList.Add(new ApplicationUserReplica { UserAccountId =Convert.ToInt32(userData.Select(x => x.UserAccountId)) });
var sdata=JsonConvert.SerializeObject(userList);
TempData["userData"] = sdata;
return RedirectToAction(nameof(LoginInfo));
}
else
{
ModelState.AddModelError("", "Please enter you username and password correctly");
}
return View(login);
}
public bool IsUserExists(string userName)
{
int c=_context.ApplicationUser.Where(x => x.UserName == userName).Count();
if (c >= 1)
{
return true;
}
else
{
return false;
}
}
[AllowAnonymous]
public ActionResult Logout()
{
_signInManager.SignOutAsync();
return RedirectToAction(nameof(Login));
}
[AllowAnonymous]
[HttpGet]
public IActionResult LoginInfo()
{
userList=JsonConvert.DeserializeObject<List<ApplicationUser>>(TempData["userData"].ToString());
TempData.Keep();
foreach(var item in userList)
{
TempData["userId"] = item.UserAccountId;
}
return View();
}
}
}

Trouble connecting ASP.NET MVC Core 2.0 with Entity Framework

I have a very simple web application, where I try to let people register a user. Therefore, I try to save user-registration data to Entity Framework, but with no luck.
I have a basic model and a basic view, so for the sake of brevity I am not going to post them as of right now, as I don't think the problem lies within them. If anybody would like to see them, I will post them. I am trying to make use of app.UseAuthentication and my guess is that some of my logic is wrong. I am trying to save to the table dbo.AspNetUsers.
Startup.cs
public Startup(IHostingEnvironment env)
{
configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile(env.ContentRootPath + "/appsettings.json")
.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<IdentityDataContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityDataContext>()
.AddDefaultTokenProviders();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute("Default", "{controller=Account}/{action=Index}");
});
app.UseFileServer();
}
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyLocalDB;Trusted_Connection=True;"
}
}
Controller
public class AccountController : Controller
{
public IActionResult Index()
{
return View(new CombinedLoginAndRegisterModel());
}
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
//Registration
[HttpPost]
public async Task<IActionResult> RegisterUser(CombinedLoginAndRegisterModel cbr)
{
var user = new IdentityUser
{
Email = cbr.Register.Email
};
var result = await _userManager.CreateAsync(user, cbr.Register.Password); //wait
return View();
}
}
Data Context
public class IdentityDataContext : IdentityDbContext<IdentityUser>
{
public IdentityDataContext(DbContextOptions<IdentityDataContext> options) : base(options)
{
Database.EnsureCreated();
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
I appreciate any help greatly and will respond to requests/comments.
EDIT
Index.cshtml
#model CS_config.Models.CombinedLoginAndRegisterModel
<h2>Register account</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary()
#Html.LabelFor(x => x.Register.Email, new { style = "margin-right: 7px;" })
#Html.TextBoxFor(x => x.Register.Email)<br><br>
#Html.LabelFor(x => x.Register.Password, new { style = "margin-right: 10px;" })
#Html.TextBoxFor(x => x.Register.Password)<br><br>
<button type="submit" name="RegisterUser">Submit</button> //named it to match the Task `RegisterUser` in the Controller
}
So I eventually found out a bunch of problems and why it didn't work. One thing I hadn't done was to do an initial migration and/or updated database with Add-Migration [name] and Update-Database
Most of my other problems are further explained in here: Controller Action not triggered - Simple Project - ASP.NET MVC CORE 2.0 - also check the comments to both this post and the linked post
If anybody has same problems, feel free to write me.

Controller methods called twice?

base controller:
public class AnaController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
ViewBag.AktifKullanici = kullaniciServis.AktifKullanici(KullaniciEposta);
base.OnActionExecuting(filterContext);
}
}
controller that is inherited from above controller:
public class AnasayfaController : AnaController
{
private HaberSitesiDbContext db;
private HaberServis haberServis;
private KullaniciServis kullaniciServis;
public AnasayfaController()
{
this.db = new HaberSitesiDbContext();
this.haberServis = new HaberServis(db);
this.kullaniciServis = new KullaniciServis(db);
}
// !!! following methods called twice !!!
public ActionResult Index()
{
return View();
}
public ActionResult _SolManset()
{
// id si 2 olanlar sol manset haberleri
var haberler = haberServis.PozisyonHaberler(2, 3)
.ToList();
return PartialView(haberler);
}
public ActionResult _Slider()
{
// id si 1 olanlar slider haberleri
var haberler = haberServis.PozisyonHaberler(1, 19)
.ToList();
return PartialView(haberler);
}
public ActionResult _Yazarlar()
{
var yazarlar = haberServis.KoseYazilari(5)
.ToList();
return PartialView(yazarlar);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
layout:
...
<article id="body">
#RenderBody()
</article>
...
Index:
<aside class="aside_small float_left">
#Html.Action("_SolManset", "Anasayfa")
</aside>
<section class="section_middle">
#Html.Action("_Slider", "Anasayfa")
</section>
<aside class="aside_small float_right">
#Html.Action("_Yazarlar", "Anasayfa")
</aside>
I cant find any solution. Any suggestion? There is no extra code, no js code. How can I find where second calling come from?

Resources