Controller that worked in ASP.NET Core 2.0:
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class GraficResourcesApiController : ControllerBase
{
private readonly ApplicationDbContext _context;
public GraficResourcesApiController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet]
public JsonResult GetGrafic(int ResourceId)
{
var sheduling = new List<Sheduling>();
var events = from e in _context.Grafic.Where(c=>c.ResourceId == ResourceId)
select new
{
id = e.Id,
title = e.Personals.Name,
start = e.DateStart,
end = e.DateStop,
color = e.Personals.Color,
personalId = e.PersonalId,
description = e.ClientName
};
var rows = events.ToArray();
return Json(rows);
}
}
in ASP.NET Core 2.1
return Json (rows);
writes that Json does not exist in the current context. If we remove Json leaving simply
return rows;
then writes that it was not possible to explicitly convert the type List () to JsonResult
How to convert to Json now?
In asp.net-core-2.1 ControllerBase does not have a Json(Object) method. However Controller does.
So either refactor the current controller to be derived from Controller
public class GraficResourcesApiController : Controller {
//...
}
to have access to the Controller.Json Method or you can initialize a new JsonResult yourself in the action
return new JsonResult(rows);
which is basically what the method does internally in Controller
/// <summary>
/// Creates a <see cref="JsonResult"/> object that serializes the specified <paramref name="data"/> object
/// to JSON.
/// </summary>
/// <param name="data">The object to serialize.</param>
/// <returns>The created <see cref="JsonResult"/> that serializes the specified <paramref name="data"/>
/// to JSON format for the response.</returns>
[NonAction]
public virtual JsonResult Json(object data)
{
return new JsonResult(data);
}
/// <summary>
/// Creates a <see cref="JsonResult"/> object that serializes the specified <paramref name="data"/> object
/// to JSON.
/// </summary>
/// <param name="data">The object to serialize.</param>
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
/// the formatter.</param>
/// <returns>The created <see cref="JsonResult"/> that serializes the specified <paramref name="data"/>
/// as JSON format for the response.</returns>
/// <remarks>Callers should cache an instance of <see cref="JsonSerializerSettings"/> to avoid
/// recreating cached data with each call.</remarks>
[NonAction]
public virtual JsonResult Json(object data, JsonSerializerSettings serializerSettings)
{
if (serializerSettings == null)
{
throw new ArgumentNullException(nameof(serializerSettings));
}
return new JsonResult(data, serializerSettings);
}
Source
I want my application to respect browser accept header and return 406, if it does not match the response format.
I have this options set in Mvc configuration:
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services">The collection of the services.</param>
/// <returns>The provider of the service.</returns>
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// add mvc services
services.AddMvc(options =>
{
options.RespectBrowserAcceptHeader = true;
options.ReturnHttpNotAcceptable = true;
options.CacheProfiles.Add(
"CodebookCacheProfile",
new CacheProfile()
{
Duration = (int)TimeSpan.FromDays(1).TotalSeconds
});
})
.AddControllersAsServices()
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new StringEmptyToNullConverter());
options.SerializerSettings.Converters.Add(new StringEnumConverter(true));
});
// add response compression services
services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
options.Providers.Add<GzipCompressionProvider>();
});
// add application services
services.AddSwaggerDoc()
.AddConfiguration(configuration)
.AddModel()
.AddDataAccess(configuration)
.AddAuthentication(configuration)
.AddDomainServices()
.AddSchedulerContainer(() => serviceProvider);
// initialize container
serviceProvider = services.CreateServiceProvider();
return serviceProvider;
}
When I try to send request like this: (with Accept header set on whatever, for example "text/xml")
I always get 200 OK - with "application/json"
My CountriesController looks like this:
/// <summary>
/// REST API controller for actions with countries.
/// </summary>
[AllowAnonymous]
[Area(Area.Common)]
[Route("[area]/Codebooks/[controller]")]
[ResponseCache(CacheProfileName = "CodebookCacheProfile")]
public class CountriesController : ApiController
{
private readonly ICountryService countryService;
/// <summary>
/// Initializes a new instance of the <see cref="CountriesController" /> class.
/// </summary>
/// <param name="countryService">The country service.</param>
public CountriesController(ICountryService countryService)
{
this.countryService = countryService ?? throw new ArgumentNullException(nameof(countryService));
}
/// <summary>
/// Gets countries by search settings.
/// </summary>
/// <response code="200">The countries was returned correctly.</response>
/// <response code="401">The unauthorized access.</response>
/// <response code="406">The not acceptable format.</response>
/// <response code="500">The unexpected error.</response>
/// <param name="countrySearchSettings">The search settings of the country.</param>
/// <returns>Data page of countries.</returns>
[HttpGet]
[ProducesResponseType(typeof(IDataPage<Country>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void), StatusCodes.Status406NotAcceptable)]
[ProducesResponseType(typeof(ApiErrorSummary), StatusCodes.Status500InternalServerError)]
[SwaggerOperation("SearchCountries")]
public IDataPage<Country> Get([FromQuery(Name = "")] CountrySearchSettings countrySearchSettings)
{
return countryService.Search(countrySearchSettings);
}
/// <summary>
/// Gets a country.
/// </summary>
/// <response code="200">The country was returned correctly.</response>
/// <response code="400">The country code is not valid.</response>
/// <response code="401">The unauthorized access.</response>
/// <response code="406">The not acceptable format.</response>
/// <response code="500">The unexpected error.</response>
/// <param name="countryCode">The code of the country.</param>
/// <returns>Action result.</returns>
[HttpGet("{countryCode}")]
[ProducesResponseType(typeof(Country), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ApiValidationErrorSummary), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void), StatusCodes.Status406NotAcceptable)]
[ProducesResponseType(typeof(ApiErrorSummary), StatusCodes.Status500InternalServerError)]
[SwaggerOperation("GetCountry")]
public IActionResult Get(string countryCode)
{
var country = countryService.GetByCode(countryCode);
return Ok(country);
}
}
Do you have any idea why the request Accept header is always ignored and the response is always 200 OK with correct Json data?
What am I missing? I thought that the setting of RespectBrowserAcceptHeader and ReturnHttpNotAcceptable would do the thing... but apparently not.
Why it always falls back to the default Json formatter?
For ReturnHttpNotAcceptable to work, the type returned by an action must be either an ObjectResult (e.g. Ok(retval)) or a type that does not implement IActionResult (in which case the MVC framework will wrap it in an ObjectResult for you).
This is because the MVC framework only checks against the value of ReturnHttpNotAcceptable in ObjectResultExecutor, and not in any of the other IActionResultExecutor implementations (like ViewResultExecutor). (See source code for ObjectResultExecutor and ViewResultExecutor)
Put simply, make sure that the type you are returning doesn't implement (or inherit from anything that implements) IActionResult.
Add the following line in your ConfigureServices method of Startup.cs
services.AddMvcCore().AddJsonFormatters().AddApiExplorer();
I am trying to get my Dialog to work with my database.
If I have my dialog like this:
[Serializable]
public class QuestionDialog : IDialog<object>
{
/// <summary>
/// Start our response
/// </summary>
/// <param name="context">The current context</param>
/// <returns></returns>
public async Task StartAsync(IDialogContext context)
{
// Move to the next method
context.Wait(StepOneAsync);
}
/// <summary>
/// When our message is recieved we execute this delegate
/// </summary>
/// <param name="context">The current context</param>
/// <param name="result">The result object</param>
/// <returns></returns>
private async Task StepOneAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
// Get our activity
var activity = await result;
// Ask our first question
await context.PostAsync("hi");
// Get our answer
context.Done(this);
}
}
Everything works fine and I get my message as expected. I then changed it to this:
[Serializable]
public class QuestionDialog : IDialog<object>
{
// Private properties
private IList<QuestionGroup> _questionGroups;
/// <summary>
/// Start our response
/// </summary>
/// <param name="context">The current context</param>
/// <returns></returns>
public async Task StartAsync(IDialogContext context)
{
try
{
// Create our service
var questionGroupService = new QuestionGroupService(new UnitOfWork<DatabaseContext>());
// Add our question groups
this._questionGroups = await questionGroupService.ListAllAsync();
// Move to the next method
context.Wait(StepOneAsync);
} catch (Exception ex)
{
}
}
/// <summary>
/// When our message is recieved we execute this delegate
/// </summary>
/// <param name="context">The current context</param>
/// <param name="result">The result object</param>
/// <returns></returns>
private async Task StepOneAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
// Get our activity
var activity = await result;
// Ask our first question
await context.PostAsync("hi");
// Get our answer
context.Done(this);
}
}
And it doesn't go the the StepOneAsync method. Can anyone see anything glaringly obvious as to why this isn't working?
Make sure your QestionGroup model is marked as Serializable.
If you cannot make it serializable and you still want to reference it during your dialog, you need to go with one of the alternatives described in the "How can I reference non-serializable services from my C# dialogs?" section of the Bot Framework Technical FAQ.
The simplest one is to use the NonSerialized attribute in your field.
Alternatively, you can try using registering the Reflection Serialization Surrogate by adding it to the Autofac container. In your global.asax, try adding this code:
var builder = new ContainerBuilder();
builder.RegisterModule(new ReflectionSurrogateModule());
builder.Update(Conversation.Container);
This question already has answers here:
How to avoid Dependency Injection constructor madness?
(10 answers)
Closed 7 years ago.
I have an MVC controller holding several abstractions (components). I want to reduce the amount of params to max 4 params.
To do this, I have several strategies that do not satisfy:
Bundling a set of params into a new class where the params will be properties: that just masks the complexity.
Resolve dependencies not by constructor injection but resolve by using factories: that also masks complexity.
Is there a better alternative approach ?
This the code of the controller:
public abstract class BaseVerificatieController : ExtendedController
{
private readonly IReferentieTabellenSysteemSettings referentieTabellenSysteemSettings;
private readonly IProcessManager processManager;
private readonly INavigationManager navigationManager;
private readonly ITransactionFacade transactionFacade;
private readonly IUISupportFacade uiSupportFacade;
private readonly ProcessIndex process;
protected BaseVerificatieController(
IBackHandler backHandler,
IReferentieTabellenSysteemSettings referentieTabellenSysteemSettings,
IProcessManager processManager,
INavigationManager navigationManager,
ITransactionFacade transactionFacade,
IUISupportFacade uiSupportFacade,
ProcessIndex process)
: base(backHandler)
{
this.referentieTabellenSysteemSettings = referentieTabellenSysteemSettings;
this.processManager = processManager;
this.navigationManager = navigationManager;
this.transactionFacade = transactionFacade;
this.uiSupportFacade = uiSupportFacade;
this.process = process;
}
[HttpGet]
public ActionResult Index()
{
var processStep = processManager.StartProcess(process);
return navigationManager.RedirectFromProcessStep(process, processStep);
}
[HttpGet]
public ActionResult Oe()
{
var model = new OeViewModel();
var transactionResult = transactionFacade.VerifyIdentityStart();
model.SetTransactionResult(transactionResult);
return View(model);
}
[HttpPost]
public ActionResult Oe(OeViewModel viewModel)
{
if (viewModel == null)
{
throw new ArgumentNullException("viewModel");
}
var transactionResult = transactionFacade.VerifyIdentityCheckRegisters(viewModel.SKN, null);
if (transactionResult.MoveToStep != Business.Models.ProcessStepIndex.NoStep)
{
return navigationManager.RedirectFromTransactionResult(process, transactionResult);
}
var model = new OeViewModel();
model.SetTransactionResult(transactionResult);
return View(model);
}
[HttpGet]
public ActionResult Oz()
{
var model = new OzViewModel(uiSupportFacade, referentieTabellenSysteemSettings);
var idStaatResult = transactionFacade.IdStaatStart();
model.SetIdStaatResult(idStaatResult);
return View("Oz_SKDB", model);
}
[HttpPost]
public ActionResult Oz(OzViewModel viewModel)
{
return RedirectToAction("Index", "Home");
}
As #Maarten says in comments, I would get rid of the injection of the process and inject it where its needed (not passing it around).
I would further move all the view model logic into "view model handlers" and use a mediator for executing the view model handlers.
The dependencies such as the transactionFacade and uiSupportFacade would then be injected in the view model handlers. This can be achieved with the following:
/// <summary>
/// Specifices that the target class is a view model. This is a marker interface and has no methods.
/// </summary>
public interface IViewModel
{
// Marker interface
}
/// <summary>
/// Handles the <typeparamref name="TViewModel"/>.
/// </summary>
/// <typeparam name="TViewModel">The view model which should be handled.</typeparam>
public interface IHandleViewModel<out TViewModel> where TViewModel : IViewModel
{
/// <summary>
/// Creates a <typeparamref name="TViewModel"/>.
/// </summary>
/// <returns>An instance of the <typeparamref name="TViewModel"/>.</returns>
TViewModel Handle();
}
/// <summary>
/// Handles the <typeparamref name="TViewModel"/> with the argument of <typeparamref name="TInput"/>
/// </summary>
/// <typeparam name="TInput">The argument for the view model</typeparam>
/// <typeparam name="TViewModel">The view model which should be handled.</typeparam>
public interface IHandleViewModel<out TViewModel, in TInput> where TViewModel : IViewModel
{
/// <summary>
/// Creates a <typeparamref name="TViewModel"/>.
/// </summary>
/// <returns>An instance of the <typeparamref name="TViewModel"/>.</returns>
TViewModel Handle(TInput input);
}
/// <summary>
/// Processes and creates view models.
/// </summary>
public interface IProcessViewModels
{
/// <summary>
/// Creates the <typeparamref name="TViewModel"/>.
/// </summary>
/// <returns>The view model</returns>
TViewModel Create<TViewModel>() where TViewModel : IViewModel;
/// <summary>
/// Create the <typeparamref name="TViewModel"/> with an argument of type <typeparamref name="TInput"/>
/// </summary>
/// <typeparam name="TViewModel">The view model which should be constructed</typeparam>
/// <typeparam name="TInput">The type of argument for the view model</typeparam>
/// <param name="input">The argument for the view model</param>
/// <returns>The view model</returns>
TViewModel Create<TViewModel, TInput>(TInput input) where TViewModel : IViewModel;
}
This means you can inject a single IProcessViewModels into your controller and execute the handlers. E.g. by filling the dependency container (here Simple Injector):
/// <summary>
/// Registers the view models in the Simple Injector container
/// </summary>
/// <param name="container">The Simple Injector container</param>
/// <param name="viewModelAssemblies">The assembly location of the view models</param>
public static void RegisterViewModels(this Container container, Assembly[] viewModelAssemblies)
{
if (container == null)
throw new ArgumentNullException("container");
if (viewModelAssemblies == null)
throw new ArgumentNullException("viewModelAssemblies");
container.RegisterSingle<IProcessViewModels, ViewModelProcessor>();
container.RegisterManyForOpenGeneric(typeof(IHandleViewModel<>), viewModelAssemblies);
container.RegisterManyForOpenGeneric(typeof(IHandleViewModel<,>), viewModelAssemblies);
}
The above code is from my "Nerve Framework" here: https://github.com/janhartmann/nerve-framework/tree/master/NerveFramework.Web.Mvc
Our team decided to use Domain Driven Design architecture for our project. Now the discussion is going on for, "can we use ASP.NET Identity in DDD?".
Is there any disadvantages on using ASP.NET identity in DDD design.
I'm in a confusion to make a decision on it.
I have searched for it, but I didn't get any idea.
Any help would be appreciable.
The questions reveals several misconceptions:
It appears that you perceive the domain model as some monolithic model where you put every piece of application in. Instead, concentrate on strategic patterns to distinguish Bounded Contexts. Consider the domain as a composition of several loosely interconnected components. Then identify what your core domain is and apply DDD tactical patterns there. Not every ccomponent needs DDD. Some of them even should not use DDD. Especially - generic domains, like Authentication.
DDD is technology agnostic (to some point) so yes, you can use ASP.NET Identity or whatever library you like.
Authentication typically belongs to the Application layer, not Domain layer.
However - if in your domain there is a concept of a user/client/person, it might be required to use the identity provided by the identity component. But you have to understand that the meaning of User in your bounded context is different than meaning of User in Identity component. These are not the same concept. Although they both refer to the same physical person sitting somewhere and clicking on your app's GUI, they are 2 different models (or projections) of him that serve different purposes. So you shouldn't just reuse the ASP.NET User class in your bounded context.
Instead - separate contexts should communicate via an anticorruption layer. Basically you have to make some service (interface only) in your bounded context that produces context-specific User objects. The implementation of that interface made in infrastructure layer will be a wrapper of ASP.NET Identity that gets ASP.NET Identity user and produce corresponding bounded context's user.
I am new to DDD. But I achieved integration with Identity and DDD. Although I doubt it truly sticks to the priciples of DDD.
I started with the Entity:
public partial class User : IdentityUser {
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager) {
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
/// <summary>
/// The Date the User Registered for general information purposes
/// </summary>
public DateTime DateRegistered { get; set; }
}
Then the Interface:
public interface IUserRepository:IBaseRepository<User> {
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
/// <returns>Identity Result</returns>
Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password);
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns>SignIn Status</returns>
Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe);
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns>SignIn Status</returns>
Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser);
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns>Identity Result</returns>
Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code);
void ForgotPassword();
void ForgotPasswordConfirmation();
void ResetPassword();
void ResetPasswordConfirmation();
void ExternalLogin();
void SendCode();
void ExternalLoginCallback();
void ExternalLoginConfirmation();
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
void Logoff(IAuthenticationManager AuthenticationManager);
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
User GetUser(string Email);
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
User GetUserById(string ID);
}
Then the Repository:
public class UserRepository : BaseRepository<User>, IUserRepository {
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns>Identity Result</returns>
public async Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code) =>
await userManager.ConfirmEmailAsync(userId, code);
public void ExternalLogin() {
throw new NotImplementedException();
}
public void ExternalLoginCallback() {
throw new NotImplementedException();
}
public void ExternalLoginConfirmation() {
throw new NotImplementedException();
}
public void ForgotPassword() {
throw new NotImplementedException();
}
public void ForgotPasswordConfirmation() {
throw new NotImplementedException();
}
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
public User GetUser(string Email) =>
_context.Users.Where(p => p.Email == Email).FirstOrDefault();
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
public User GetUserById(string ID) =>
_context.Users.Find(ID);
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns>SignIn Status</returns>
public async Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe) =>
await signinManager.PasswordSignInAsync(email, password, rememberMe, shouldLockout: false);
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
public void Logoff(IAuthenticationManager AuthenticationManager) {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
}
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
/// <returns>Identity Result</returns>
public async Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password) =>
await userManager.CreateAsync(user, password);
public void ResetPassword() {
throw new NotImplementedException();
}
public void ResetPasswordConfirmation() {
throw new NotImplementedException();
}
public void SendCode() {
throw new NotImplementedException();
}
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns>SignIn Status</returns>
public async Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser) =>
await signinManager.TwoFactorSignInAsync(provider, code, isPersistent: rememberMe, rememberBrowser: rememberBrowser);
}
IService:
public interface IUserService {
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
/// <returns></returns>
Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password);
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns></returns>
Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe);
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns></returns>
Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser);
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns></returns>
Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code);
void ForgotPassword();
void ForgotPasswordConfirmation();
void ResetPassword();
void ResetPasswordConfirmation();
void ExternalLogin();
void SendCode();
void ExternalLoginCallback();
void ExternalLoginConfirmation();
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
void Logoff(IAuthenticationManager AuthenticationManager);
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
User GetUser(string Email);
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
User GetUserById(string ID);
}
Service:
public class UserService : ServiceBase, IUserService {
#region Private Field
private IUserRepository _userRepository;
#endregion
#region Constructor
/// <summary>
/// Constructor to initialise User Repository
/// </summary>
/// <param name="userRepository"></param>
public UserService(IUserRepository userRepository) {
_userRepository = userRepository;
}
#endregion
#region Methods
/// <summary>
/// Confirm email of User
/// </summary>
/// <param name="userManager">User Manager to handle confirmation</param>
/// <param name="userId">String user Id of the User</param>
/// <param name="code">User code sent in Email</param>
/// <returns>Identity Result</returns>
public Task<IdentityResult> ConfirmEmail(UserManager<User, string> userManager, string userId, string code) =>
_userRepository.ConfirmEmail(userManager, userId, code);
public void ExternalLogin() {
throw new NotImplementedException();
}
public void ExternalLoginCallback() {
throw new NotImplementedException();
}
public void ExternalLoginConfirmation() {
throw new NotImplementedException();
}
public void ForgotPassword() {
throw new NotImplementedException();
}
public void ForgotPasswordConfirmation() {
throw new NotImplementedException();
}
/// <summary>
/// Get user based on their Email
/// </summary>
/// <param name="Email">Email of user</param>
/// <returns>User</returns>
public User GetUser(string Email) {
throw new NotImplementedException();
}
/// <summary>
/// Get User by their GUID
/// </summary>
/// <param name="ID">GUID</param>
/// <returns>User</returns>
public User GetUserById(string ID) {
throw new NotImplementedException();
}
/// <summary>
/// Login User
/// </summary>
/// <param name="signinManager">Signin Manager to handle login</param>
/// <param name="email">Email of user</param>
/// <param name="password">Password of user</param>
/// <param name="rememberMe">Boolean if the user wants to be remembered</param>
/// <returns>SignIn Status</returns>
public Task<SignInStatus> Login(SignInManager<User, string> signinManager, string email, string password, bool rememberMe) =>
_userRepository.Login(signinManager, email, password, rememberMe);
/// <summary>
/// Log off user from the Application
/// </summary>
/// <param name="AuthenticationManager">Application Manager to handle Sign out</param>
public void Logoff(IAuthenticationManager AuthenticationManager) {
_userRepository.Logoff(AuthenticationManager);
}
/// <summary>
/// Register User to Identity Database
/// </summary>
/// <param name="userManager">User Manager to Handle Registration</param>
/// <param name="user">User to add to database</param>
/// <param name="password">User's password</param>
public Task<IdentityResult> Register(UserManager<User, string> userManager, User user, string password) =>
_userRepository.Register(userManager, user, password);
public void ResetPassword() {
throw new NotImplementedException();
}
public void ResetPasswordConfirmation() {
throw new NotImplementedException();
}
public void SendCode() {
throw new NotImplementedException();
}
/// <summary>
/// Verify that code sent to User is valid
/// </summary>
/// <param name="signinManager">Signin Manager to handle verification</param>
/// <param name="provider">Provider of the code</param>
/// <param name="code">The code</param>
/// <param name="rememberMe">Boolean if user wants to be remembered</param>
/// <param name="rememberBrowser">Boolean if browser should be remembered</param>
/// <returns>SignIn Status</returns>
public Task<SignInStatus> VerifyCode(SignInManager<User, string> signinManager, string provider, string code, bool rememberMe, bool rememberBrowser) =>
_userRepository.VerifyCode(signinManager, provider, code, rememberMe, rememberBrowser);
#endregion
}
You can use anything you like. But be aware of pollution particular solution is going to make. If your domain model gets messed up with hundreds of lines of asp.net technical kind of plumbing code that makes your domain logic hard to perceive and you are missing point of DDD.
In ideal situation - your domain model should depend only on programming language.
Also - you might find something useful from my long time ago implementation of user session related code.