How to call a custom identity Register method from a controller in .net core 2.1 mvc - asp.net-core-mvc

I want to use custom register identity method that is called in a controller to Register users automatically with a corresponding role. Here the code that I found so far:
public class RegisterUsers
{
private readonly UserManager<ApplicationUser> _userManager;
public RegisterUsers(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task SystmRegisterUsers(string uname, string sysid, string Email)
{
var newuser = new ApplicationUser
{
UserName = uname,
Email = Email,
SystemuserID = sysid
};
string UserPassword = PasswordGenerator.Generate(6, 3, true, true, true, true);
//var _user = await UserManager.FindByEmailAsync(Configuration.GetSection("UserSettings")["UserEmail"]);
var createParentUser = await _userManager.CreateAsync(newuser, UserPassword);
if (createParentUser.Succeeded)
{
//here we tie the new user to the "Admin" role
await _userManager.AddToRoleAsync(newuser, "Parent");
}
}
}
And I want to call the method SystmRegisterUsers like this in a controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("fullname,id,email,...")]MyModel parent)
{
if (ModelState.IsValid)
{
//create new records
_context.Add(parent);
await _context.SaveChangesAsync();
// and i want to call the method here to create identity users using the data entered:
var instance = new RegisterUsers();
await instance.SystmRegisterUsers(parent.FullName, parent.Parentid, parent.Parentid);
}
return View(parent);
}
And it is saying I’m missing an argument that is corresponds to userManager . I don’t even know if it is the right way to do what I want to do, I think I’m missing some basic thing please help!

For RegisterUsers, it needs UserManager<ApplicationUser> userManager, for resolving the RegisterUsers from Dependency Injection, you could follow steps below:
Register RegisterUsers in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
//your rest code
services.AddScoped<RegisterUsers>();
}
Initialize RegisterUsers by Dependency Injection
public class HomeController : Controller
{
private readonly RegisterUsers _registerUsers;
public HomeController(RegisterUsers registerUsers)
{
_registerUsers = registerUsers;
}
public async Task<IActionResult> Index()
{
await _registerUsers.SystmRegisterUsers("a1", "b1", "c1");
return View();
}

Related

Conditional validation based on request route with asp.net core 2.2 and FluentValidation

So Basically i wrote a validator for my class with FluentValidation and also a filter to do the validation task for me in my webAPI project, so far it's OK but assume that my User class has firstname,lastname,email,password properties
and i have two routes (one for register and the other one for login)
and as you might have noticed required properties are different on these route.
Thus,should I really need to write individual validation for each and every action i have?because this makes a lot of code code duplication and it's hard to change.is there any way to just add required condition based on the request coming with single validation class?
Any suggestion???
A better practice would be to use a factory pattern for your validations and use a an action filter to short circuit bad requests. You could validate any action argument(Headers, Request Bodies, etc..) with something like this.
public class TestValidationAttribute : Attribute, IActionFilter
{
private string _requestModelName;
public TestValidationAttribute(string requestModelName)
{
_requestModelName = requestModelName;
}
public void OnActionExecuting(ActionExecutingContext context)
{
// using Microsoft.Extensions.DependencyInjection;
var services = context.HttpContext.RequestServices;
var accessor = services.GetService<IHttpContextAccessor>();
var factory = services.GetService<ITestValidatorFactory>();
var tokens = accessor.HttpContext.GetRouteData().DataTokens;
if (!tokens.TryGetValue("RouteName", out var routeNameObj))
{
throw new Exception($"Action doesn't have a named route.");
}
var routeName = routeNameObj.ToString();
var validator = factory.Create(routeName);
if (!context.ActionArguments.TryGetValue(_requestModelName, out var model))
{
throw new Exception($"Action doesn't have argument named {_requestModelName}.");
}
TestModel test;
try
{
test = (TestModel) model;
}
catch (InvalidCastException)
{
throw new Exception($"Action argument can't be casted to {nameof(TestModel)}.");
}
var validation = validator.Validate(test);
if (!validation.Successful)
{
context.Result = new BadRequestObjectResult(validation.ResponseModel);
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
public class TestController : Controller
{
[HttpPost]
[Route("Test/{id}", Name = "TestGet")]
[TestValidation("model")]
public IActionResult Test(TestModel model)
{
return Ok();
}
}
public class ValidationResult
{
public bool Successful { get; }
public ResponseModel ResponseModel { get; }
}
public class TestModel
{
}
public interface ITestValidator
{
ValidationResult Validate(TestModel model);
}
public interface ITestValidatorFactory
{
ITestValidator Create(string routeName);
}

Mediator Api call failing

I'm trying to make a simple request using mediator and .net core. I'm getting an error that I am not understanding. All I'm trying to do is a simple call to get back a guid.
BaseController:
[Route("api/[controller]/[action]")]
[ApiController]
public class BaseController : Controller
{
private IMediator _mediator;
protected IMediator Mediator => _mediator ?? (_mediator = HttpContext.RequestServices.GetService<IMediator>());
}
Controller:
// GET: api/Customer/username/password
[HttpGet("{username}/{password}", Name = "Get")]
public async Task<ActionResult<CustomerViewModel>> Login(string username, string password)
{
return Ok(await Mediator.Send(new LoginCustomerQuery { Username = username,Password = password }));
}
Query:
public class LoginCustomerQuery : IRequest<CustomerViewModel>
{
public string Username { get; set; }
public string Password { get; set; }
}
View Model:
public class CustomerViewModel
{
public Guid ExternalId { get; set; }
}
Handler:
public async Task<CustomerViewModel> Handle(LoginCustomerQuery request, CancellationToken cancellationToken)
{
var entity = await _context.Customers
.Where(e =>
e.Username == request.Username
&& e.Password == Encypt.EncryptString(request.Password))
.FirstOrDefaultAsync(cancellationToken);
if (entity.Equals(null))
{
throw new NotFoundException(nameof(entity), request.Username);
}
return new CustomerViewModel
{
ExternalId = entity.ExternalId
};
}
This is the exception I am getting:
Please let me know what else you need to determine what could be the issue. Also, be kind I have been away from c# for a while.
Thanks for the info it was the missing DI. I added this
// Add MediatR
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
services.AddMediatR(typeof(LoginCustomerQueryHandler).GetTypeInfo().Assembly);
and we are good to go.

Web Api 2 Autofac AuthorizeAttribute Property Injection Doesnt Work

Trying to inject property to my custom AuthorizeAttribute but this attribute always comes null. Is this registration wrong?
public class AuthenticateAttribute : AuthorizeAttribute
{
public IAuthenticationService authenticationService { get; set; }
public UserTypes UserType;
public AuthenticateAttribute()
{
}
}
Calling From Global Asax
public static void InitializeDependencies()
{
var builder = new ContainerBuilder();
var config = GlobalConfiguration.Configuration;
builder.RegisterAssemblyTypes(Assembly.Load("BusinessServices"))
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(Assembly.Load("BusinessEntities"))
.Where(t => t.Name.EndsWith("Helper"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(config);
builder.Register(x => new ApiExceptionHandler(x.Resolve<ILogService>())).AsWebApiExceptionFilterFor<ApiController>().InstancePerLifetimeScope();
builder.RegisterType<AuthenticateAttribute>().PropertiesAutowired().InstancePerLifetimeScope();
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
Authentication Service
public class AuthenticationService : IAuthenticationService
{
private readonly IUnitOfWork unitOfWork;
private readonly IAutoMapperHelper mapper;
public AuthenticationService(IUnitOfWork _unitOfWork, IAutoMapperHelper _mapper)
{
unitOfWork = _unitOfWork;
mapper = _mapper;
}
}
I can't use authenticate attribute as constructor injected because i can't use it on methods.
[Authenticate] //How can i pass authenticationService parameter to it, if i use constructor injection?
[HttpPost]
public async Task<ConnectSocialPlatformsResponseModel> ConnectSocialPlatforms(ConnectSocialPlatformsRequestModel model)
{
if (ModelState.IsValid)
return await authenticationService.ConnectSocialPlatforms(model);
else
return validationHelper.CreateResponse<ConnectSocialPlatformsResponseModel>(ModelState);
}

UserManager in ApiController

In my project HttpContext is a member of Controller and I can use it in AccountController : Controller. But I can't access an information about current user in ApiController in contraction like
public class AccountController : ApiController
{
public UserManager<ApplicationUser> UserManager { get; private set; }
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.Current.GetOwinContext().Authentication;
}
}
}
So how to write custom ApiController right?
In the method below user variable shows me null on breakpoint. How can I retrive current user if I know that hi is logined?
public IHttpActionResult GetUser(int id)
{
var manager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
var userid = User.Identity.GetUserId();
var user = manager.FindById(userid);
var data = new Person {Name = user.UserName, Age = 99};
return Ok(data);
}
From within any controller method you can do this.GetRequestContext().User to get the currently authenticated user. The static HttpContext.Current is not supported by WebApi.
manager.FindById(userid) retrieves a user from the database as opposed to the current . To get the current user, simply access the User property within your ApiController:
public class MyApiController : ApiController
{
IPrincipal GetCurrentUser(){
return User;
}
}
This may help you:
protected string UserId { get { return User.Identity.GetUserId(); } }

Put, Delete... Method not allowed in Orchard

I've created WebApi controller based on following tutorial: sebastienros website
My modules name is Company.Accounts.
public class AccountController : ApiController
{
[HttpPost]
public string LogIn([FromBody] UserModel user)
{
// this is working
return this.accountService.LogIn(user.UserName, user.Password);
}
[HttpPut]
public string SomePuthMethod([FromBody] UserModel user)
{
// method not allowed
// some code...
}
}
Implementation of IHttpRouteProvider looks like:
private IEnumerable<RouteDescriptor> GetAccountRoute()
{
yield return new HttpRouteDescriptor
{
Name = "Account",
Priority = 10,
RouteTemplate = "Api/Account",
Defaults = new
{
area = "Company.Accounts",
controller = "Account"
}
};
}
Unfortunately, everything except GET and POST *is not working*. I'm getting simple
Method not allowed.
What's wrong? My Orchard version is 1.7.1.
You put them in the MethodNames public HttpResponseMessage Post([FromBody]...){}

Resources