Files
Judah Gabriel Himango 09396baf35 Even more formatting fixes.
2019-06-26 12:09:42 -05:00

136 lines
5.1 KiB
Markdown

# RavenDB.Identity Sample
This is an AspNetCore MVC sample that shows how to use Raven.Identity.
There are five areas of interest:
1. [appsettings.json](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/appsettings.json) - where we configure our connection to Raven.
2. [AppUser.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Models/AppUser.cs) - our user class containing any user data like FirstName and LastName.
3. [RavenController.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Controllers/RavenController.cs) - where we save changes to Raven after actions finish executing.
4. [AccountController.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Controllers/AccountController.cs) - where we register users, sign in, change roles.
5. [Startup.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Startup.cs) - where we wire up everything.
More details below.
## 1. appsettings.json - connection to Raven
Our [appsettings.json file](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/appsettings.json) defines our connection to Raven. This is done using the [RavenDB.DependencyInjection](https://github.com/JudahGabriel/RavenDB.DependencyInjection/) package.
```json
"RavenSettings": {
"Urls": [
"http://live-test.ravendb.net"
],
"DatabaseName": "Raven.Identity.Sample.Mvc",
"CertFilePath": "",
"CertPassword": ""
},
```
## 2. [AppUser.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Models/AppUser.cs)
We create our own [AppUser class](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Models/AppUser.cs) to hold user data:
```csharp
public class AppUser : Raven.Identity.IdentityUser
{
/// <summary>
/// The full name of the user.
/// </summary>
public string FullName { get; set; }
}
```
While this step isn't strictly necessary -- it's possible to skip AppUser and just use the built-in `Raven.Identity.IdentityUser` -- we recommend creating an AppUser class so you can extend your users with app-specific data.
## 3. [RavenController.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Controllers/RavenController.cs)
We need to `.SaveChangesAsync()` for anything to persist in Raven. Where should we do this?
While we could call `.SaveChangesAsync()` in every controller action, that is tedious and error prone. Instead, we create a base controller, [RavenController.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Controllers/RavenController.cs):
```csharp
/// <summary>
/// A controller that calls DbSession.SaveChangesAsync() when an action finishes executing successfully.
/// </summary>
public class RavenController : Controller
{
public RavenController(IAsyncDocumentSession dbSession)
{
this.DbSession = DbSession;
}
public IAsyncDocumentSession DbSession { get; private set; }
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var executedContext = await next.Invoke();
if (executedContext.Exception == null)
{
await DbSession.SaveChangesAsync();
}
}
}
```
## 4. [AccountController.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Controllers/AccountController.cs)
In [AccountController.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/Mvc/Controllers/AccountController.cs), we inherit from RavenController, then use the standard AspNetCore identity APIs to do registration, sign in, role change, and more:
```csharp
public class AccountController : RavenController
{
[HttpPost]
public async Task<IActionResult> Register(RegisterModel model)
{
// Register a new user.
var appUser = new AppUser
{
Email = model.Email,
UserName = model.Email
};
var createUserResult = await this.userManager.CreateAsync(appUser, model.Password);
...
}
}
```
Likewise for sign-in:
```csharp
public async Task<IActionResult> SignIn(SignInModel model)
{
var signInResult = await this.signInManager.PasswordSignInAsync(model.Email, model.Password, true, false);
if (signInResult.Succeeded)
{
return RedirectToAction("Index", "Home");
}
...
}
```
## 5. Start.cs, wiring it all together
In [Startup.cs](https://github.com/JudahGabriel/RavenDB.Identity/blob/master/Samples/RazorPages/Startup.cs), we wire up all of the above steps:
```csharp
public void ConfigureServices(IServiceCollection services)
{
...
services
.AddRavenDbDocStore() // Create our IDocumentStore singleton using the database settings in appsettings.json
.AddRavenDbAsyncSession() // Create an Raven IAsyncDocumentSession for every request.
.AddRavenDbIdentity<AppUser>(); // Let Raven store users and roles.
}
```
Finally, make sure you call `app.UseAuthentication()` inside Configure:
```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseAuthentication();
...
}
```