The standard way in Microsoft Web Applications to authenticate a user is to use Identity Framework. This will be neeeded so that people will be able to login to the site and have their calendars saved. I’ve used Identity framework before, so I wasn’t expecting that muc to be different. Although it wasnt the general setup was.
Rather than trying to add it to an exisiting project, I cheated a little and created a new project, then copied all the items I had changed across to the new project. Obviously I could only do this as I had only just started the project.
For some reason the default user interface is all within a nuget package and you have to use the “scaffold” function to generate the files. To do this you need to right click on the project:
We then get to see the “AddNew Scaffolc Item” screen, we then select “Identity”:
Finally we can then select the files that we need to generate:
Once these are generated we can then start to edit the files. The biggest mistake that I made was that the default layout file isn’t the default for the identity files. This isthe layout.cshtml file. You’ll also need to make sure that in your startup file you change the settings so that it does not use the default UI.
services.AddIdentity<IdentityUser, IdentityRole>((options) =>
{
options.Stores.MaxLengthForKeys = 128;
options.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>((options) => {
options.Password.RequiredLength = 8;
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.User.RequireUniqueEmail = true;
});
This also took a while to find out, however thankfully stackoverflow came to the rescue. You should also know that when you do not use the “default” settings you also need to specify the Email Service, so that you can send emails etc So You’ll need to register the service and you’ll also need to implement “IEmailSender”.
To start, add this following line into your startup file.
services.AddTransient<IEmailSender, PlingoEmailSender>();
Then you will need to create the IEmailSender. The file for Plingo, looks a little like the folowing:
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using System.Net.Mail;
using System.Threading.Tasks;
using uk.plingo.shift.blazor.Data.Config;
namespace uk.plingo.shift.blazor.Data
{
public class PlingoEmailSender : IEmailSender
{
private readonly IOptions<SMTPConfig> SMTPConfig;
public PlingoEmailSender(IOptions<SMTPConfig> config)
{
SMTPConfig = config;
}
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
{
// do nothing at present.
MailMessage mailMessage = new MailMessage()
{
Subject = subject,
Body = htmlMessage,
IsBodyHtml = true
};
mailMessage.To.Add(new MailAddress(email));
mailMessage.From = new MailAddress(SMTPConfig.Value.From);
SmtpClient smtpClient = new SmtpClient(SMTPConfig.Value.Host, SMTPConfig.Value.Port);
smtpClient.Credentials = new System.Net.NetworkCredential(SMTPConfig.Value.UserName, SMTPConfig.Value.Password);
smtpClient.EnableSsl = SMTPConfig.Value.EnableSsl;
smtpClient.SendAsync(mailMessage, null);
}
}
}
This then leads us to the next issues. Configuration. in .Net Core you no longer seem to use App.Config, and you cant acccess te settings through:
Settings.Default.Example
So what do you have to do, You use the appsettings.json file. So to start off with, you add your settings in:
{
"SMTP": {
"Host": "plingo.uk",
"From": "[email protected]",
"Alias": "No Reply",
"EnableSsl": true,
"UserName": "[email protected]",
"Password": "PASSWORD"
},
}
Then you create a class that is essentially the serialised version:
namespace uk.plingo.shift.blazor.Data.Config
{
public class SMTPConfig
{
public string Host { get; set; }
public int Port { get; set; }
public string From { get; set; }
public string Alias { get; set; }
public bool EnableSsl { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public SMTPConfig()
{
Port = 587;
}
}
}
Then within the Program.cs file you need to tell the web application about the configuration file:
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
})
Finally in our startup file we then tell the system which section in the configuration is our settings file:
services.Configure<SMTPConfig>(Configuration.GetSection("SMTP"));
To use this we simply add in the IOptions<SMTPConfig> parameter into the constructor of the files that we want to use it within – and then it should all work.
public PlingoEmailSender(IOptions<SMTPConfig> config)
{
SMTPConfig = config;
}
This has been a lot of relatively new bits and bobs to work out this week. Its been interesting to work out and see the changes / differences between .NET framework and .NET Core. I really do like the configuration file being JSON, is seems more descriptive then just adding key / values.