How to use await in asp.net webapi post method - asp.net-web-api

I am using entity framework and asp.net web API. I want to make the following method async but I do not know where to use await in following code.
[HttpPost]
public async Task<IHttpActionResult> CreateAccount([FromUri]string fullname, string email, string cnic,string username,string password, string logrol )
{
using (var entity = new Smock_DBEntities())
{
Person pr = new Person();
pr.Full_Name = fullname;
pr.Email = email;
pr.CNIC = cnic;
entity.Persons.Add(pr);
entity.SaveChanges();
int prID = entity.Persons.Where(per => per.CNIC == cnic).Select(per => per.Person_ID).First();
Login log = new Login();
log.Person_ID = prID;
log.Username = username;
log.Password = password;
log.Login_Role = logrol;
entity.Logins.Add(log);
entity.SaveChanges();
return Ok();
}
}

Putting it as an answer with possible places(3 places) where you can put await in your code snippet.
[HttpPost]
public async Task<IHttpActionResult> CreateAccount([FromUri]string fullname, string email, string cnic,string username,string password, string logrol )
{
using (var entity = new Smock_DBEntities())
{
Person pr = new Person();
pr.Full_Name = fullname;
pr.Email = email;
pr.CNIC = cnic;
entity.Persons.Add(pr);
await entity.SaveChangesAsync();
int prID = await entity.Persons.Where(per => per.CNIC == cnic).Select(per => per.Person_ID).FirstAsync();
Login log = new Login();
log.Person_ID = prID;
log.Username = username;
log.Password = password;
log.Login_Role = logrol;
entity.Logins.Add(log);
await entity.SaveChangesAsync();
return Ok();
}
}

Related

missing email claims from info.principal.claims

startup.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
namespace Rocky.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ExternalLoginModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly ILogger<ExternalLoginModel> _logger;
public ExternalLoginModel(
SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager,
ILogger<ExternalLoginModel> logger,
IEmailSender emailSender)
{
_signInManager = signInManager;
_userManager = userManager;
_logger = logger;
_emailSender = emailSender;
}
[BindProperty]
public InputModel Input { get; set; }
public string ProviderDisplayName { get; set; }
public string ReturnUrl { get; set; }
[TempData]
public string ErrorMessage { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string FullName { get; set; }
[Required]
public string phoneNumber { get; set; }
}
public IActionResult OnGetAsync()
{
return RedirectToPage("./Login");
}
public IActionResult OnPost(string provider, string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties);
}
public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToPage("./Login", new {ReturnUrl = returnUrl });
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor : true);
if (result.Succeeded)
{
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
return LocalRedirect(returnUrl);
}
if (result.IsLockedOut)
{
return RedirectToPage("./Lockout");
}
else
{
// If the user does not have an account, then ask the user to create an account.
ReturnUrl = returnUrl;
ProviderDisplayName = info.ProviderDisplayName;
if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
{
Input = new InputModel
{
Email = info.Principal.FindFirstValue(ClaimTypes.Email)
};
}
Input = new InputModel
{
Email = info.Principal.FindFirstValue(ClaimTypes.Email),
FullName= info.Principal.FindFirstValue(ClaimTypes.Name),
};
return Page();
}
}
public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information during confirmation.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
if (ModelState.IsValid)
{
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
// If account confirmation is required, we need to show the link if we don't have a real email sender
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email });
}
await _signInManager.SignInAsync(user, isPersistent: false, info.LoginProvider);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
ProviderDisplayName = info.ProviderDisplayName;
ReturnUrl = returnUrl;
return Page();
}
}
}
externallogin.cshtml.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
namespace Rocky.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ExternalLoginModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly ILogger<ExternalLoginModel> _logger;
public ExternalLoginModel(
SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager,
ILogger<ExternalLoginModel> logger,
IEmailSender emailSender)
{
_signInManager = signInManager;
_userManager = userManager;
_logger = logger;
_emailSender = emailSender;
}
[BindProperty]
public InputModel Input { get; set; }
public string ProviderDisplayName { get; set; }
public string ReturnUrl { get; set; }
[TempData]
public string ErrorMessage { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string FullName { get; set; }
[Required]
public string phoneNumber { get; set; }
}
public IActionResult OnGetAsync()
{
return RedirectToPage("./Login");
}
public IActionResult OnPost(string provider, string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties);
}
public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToPage("./Login", new {ReturnUrl = returnUrl });
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor : true);
if (result.Succeeded)
{
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
return LocalRedirect(returnUrl);
}
if (result.IsLockedOut)
{
return RedirectToPage("./Lockout");
}
else
{
// If the user does not have an account, then ask the user to create an account.
ReturnUrl = returnUrl;
ProviderDisplayName = info.ProviderDisplayName;
if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
{
Input = new InputModel
{
Email = info.Principal.FindFirstValue(ClaimTypes.Email)
};
}
return Page();
}
}
public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
// Get the information about the user from the external login provider
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information during confirmation.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
if (ModelState.IsValid)
{
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
// If account confirmation is required, we need to show the link if we don't have a real email sender
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email });
}
await _signInManager.SignInAsync(user, isPersistent: false, info.LoginProvider);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
ProviderDisplayName = info.ProviderDisplayName;
ReturnUrl = returnUrl;
return Page();
}
}
}
i want to populate email of fb user while registration but email claim is missing from info.principal.claims in externallogin.cs
i m getting null i tried so many approches but failed if anyone know how to solve this i m using .net 5 and included package for Facebook 5.0.17
image of getting null as email

How to get result value from WebAPI in Xamarin

public async Task<Customer> GetCustomersAsync(string id)
{
var prod = new Customer();
HttpClient client = new HttpClient();
string url = "https://xxxxxx.com/api/Customers/" + id;
client.BaseAddress = new Uri(url);
HttpResponseMessage response = await client.GetAsync("");
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
prod = JsonConvert.DeserializeObject<Customer>(content);
}
return await Task.FromResult(prod);
}
Class Customer(Models)
public class Customer
{
public string CodeRandom { get; set; }
public string NameUs { get; set; }
}
I do make a call to the API to get the results. However I can't get the return result when .Result
This is how I do it:
var infocustomer = customerRepository.GetCustomersAsync(userrating);
string nameus = infocustomer.Result.NameUs;
When I debug, nameus exits by itself. Please give me any solution. Thank you
instead of this
string content = response.Content.ReadAsStringAsync().Result;
do this
string content = await response.Content.ReadAsStringAsync();
and then just
return prod;

Sign-in user via remote services and about TokenAuthController

I need to sign-in the user using only remote services. I think using TokenAuthController in Web.Core application
I really can't understand why the snippet given below doesn't work. I have added a new method called Login in TokenAuthController .
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using Abp.Runtime.Security;
using Abp.UI;
using Abp.Web.Models;
using Microsoft.AspNetCore.Authorization;
using TSE.DergiAbone.Authentication.External;
using TSE.DergiAbone.Authentication.JwtBearer;
using TSE.DergiAbone.Authorization;
using TSE.DergiAbone.Authorization.Users;
using TSE.DergiAbone.Identity;
using TSE.DergiAbone.Models.TokenAuth;
using TSE.DergiAbone.MultiTenancy;
namespace TSE.DergiAbone.Controllers
{
[Route("api/[controller]/[action]")]
public class TokenAuthController : DergiAboneControllerBase
{
private readonly LogInManager _logInManager;
private readonly SignInManager _signInManager;
private readonly ITenantCache _tenantCache;
private readonly AbpLoginResultTypeHelper _abpLoginResultTypeHelper;
private readonly TokenAuthConfiguration _configuration;
private readonly IExternalAuthConfiguration _externalAuthConfiguration;
private readonly IExternalAuthManager _externalAuthManager;
private readonly UserRegistrationManager _userRegistrationManager;
public TokenAuthController(
LogInManager logInManager,
SignInManager signInManager,
ITenantCache tenantCache,
AbpLoginResultTypeHelper abpLoginResultTypeHelper,
TokenAuthConfiguration configuration,
IExternalAuthConfiguration externalAuthConfiguration,
IExternalAuthManager externalAuthManager,
UserRegistrationManager userRegistrationManager)
{
_logInManager = logInManager;
_tenantCache = tenantCache;
_abpLoginResultTypeHelper = abpLoginResultTypeHelper;
_configuration = configuration;
_externalAuthConfiguration = externalAuthConfiguration;
_externalAuthManager = externalAuthManager;
_userRegistrationManager = userRegistrationManager;
_signInManager = signInManager;
}
***[HttpPost]
public virtual async Task<JsonResult> Login(string UserName, string password,bool IsPersistent )
{
var loginResult = await GetLoginResultAsync(UserName, password, GetTenancyNameOrNull());
//var result = await _signInManager.SignInAsync(loginResult.Identity, IsPersistent);
var result = await _signInManager.PasswordSignInAsync(UserName, password, true, false);
if (result.Succeeded)
{
long bak= User.Identity.GetUserId().Value;
string res = "User signed in";
}
await UnitOfWorkManager.Current.SaveChangesAsync();
bool chk = User.Identity.IsAuthenticated;
return Json(new Abp.Web.Models.AjaxResponse { TargetUrl = "" });
}***
[HttpPost]
public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model)
{
var loginResult = await GetLoginResultAsync(
model.UserNameOrEmailAddress,
model.Password,
GetTenancyNameOrNull()
);
//var chk = _logInManager.LoginAsync("jimycarbonare#gmail.com", "123qwe", "TSEDergi").Result;
//var chk2 = _logInManager.Login("jimycarbonare#gmail.com", "123qwe", "TSEDergi");
//var name = User.Identity.Name;
//bool bak0 = User.IsInRole("admin");
//var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
//var loginResult = await GetLoginResultAsync("jimycarbonare#gmail.com", "123qwe", "TSEDergi");
//await _signInManager.SignInAsync(loginResult.Identity, model.RememberClient);//_logInManager.LoginAsync("jimycarbonare#gmail.com", "123qwe", "TSEDergi").Result;
//var name = User.Identity.Name;
//bool bak0 = User.IsInRole("admin");
var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
return new AuthenticateResultModel
{
AccessToken = accessToken,
EncryptedAccessToken = GetEncrpyedAccessToken(accessToken),
ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
UserId = loginResult.User.Id
};
}
[HttpGet]
public List<ExternalLoginProviderInfoModel> GetExternalAuthenticationProviders()
{
return ObjectMapper.Map<List<ExternalLoginProviderInfoModel>>(_externalAuthConfiguration.Providers);
}
[HttpPost]
public async Task<ExternalAuthenticateResultModel> ExternalAuthenticate([FromBody] ExternalAuthenticateModel model)
{
var externalUser = await GetExternalUserInfo(model);
var loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), GetTenancyNameOrNull());
switch (loginResult.Result)
{
case AbpLoginResultType.Success:
{
var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
return new ExternalAuthenticateResultModel
{
AccessToken = accessToken,
EncryptedAccessToken = GetEncrpyedAccessToken(accessToken),
ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
};
}
case AbpLoginResultType.UnknownExternalLogin:
{
var newUser = await RegisterExternalUserAsync(externalUser);
if (!newUser.IsActive)
{
return new ExternalAuthenticateResultModel
{
WaitingForActivation = true
};
}
// Try to login again with newly registered user!
loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), GetTenancyNameOrNull());
if (loginResult.Result != AbpLoginResultType.Success)
{
throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
loginResult.Result,
model.ProviderKey,
GetTenancyNameOrNull()
);
}
return new ExternalAuthenticateResultModel
{
AccessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity)),
ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
};
}
default:
{
throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
loginResult.Result,
model.ProviderKey,
GetTenancyNameOrNull()
);
}
}
}
private async Task<User> RegisterExternalUserAsync(ExternalAuthUserInfo externalUser)
{
var user = await _userRegistrationManager.RegisterAsync(
externalUser.Name,
externalUser.Surname,
externalUser.EmailAddress,
externalUser.EmailAddress,
Authorization.Users.User.CreateRandomPassword(),
true
);
user.Logins = new List<UserLogin>
{
new UserLogin
{
LoginProvider = externalUser.Provider,
ProviderKey = externalUser.ProviderKey,
TenantId = user.TenantId
}
};
await CurrentUnitOfWork.SaveChangesAsync();
return user;
}
private async Task<ExternalAuthUserInfo> GetExternalUserInfo(ExternalAuthenticateModel model)
{
var userInfo = await _externalAuthManager.GetUserInfo(model.AuthProvider, model.ProviderAccessCode);
if (userInfo.ProviderKey != model.ProviderKey)
{
throw new UserFriendlyException(L("CouldNotValidateExternalUser"));
}
return userInfo;
}
private string GetTenancyNameOrNull()
{
if (!AbpSession.TenantId.HasValue)
{
return null;
}
return _tenantCache.GetOrNull(AbpSession.TenantId.Value)?.TenancyName;
}
[HttpPost]
public AbpLoginResult<Tenant, User> GetLoginResult2Async(string usernameOrEmailAddress, string password, string tenancyName)
{
var loginResult = _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName).Result;
switch (loginResult.Result)
{
case AbpLoginResultType.Success:
return loginResult;
default:
throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
}
}
private async Task<AbpLoginResult<Tenant, User>> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
{
var loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);
switch (loginResult.Result)
{
case AbpLoginResultType.Success:
return loginResult;
default:
throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
}
}
private string CreateAccessToken(IEnumerable<Claim> claims, TimeSpan? expiration = null)
{
var now = DateTime.UtcNow;
var jwtSecurityToken = new JwtSecurityToken(
issuer: _configuration.Issuer,
audience: _configuration.Audience,
claims: claims,
notBefore: now,
expires: now.Add(expiration ?? _configuration.Expiration),
signingCredentials: _configuration.SigningCredentials
);
return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
}
private static List<Claim> CreateJwtClaims(ClaimsIdentity identity)
{
var claims = identity.Claims.ToList();
var nameIdClaim = claims.First(c => c.Type == ClaimTypes.NameIdentifier);
// Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
claims.AddRange(new[]
{
new Claim(JwtRegisteredClaimNames.Sub, nameIdClaim.Value),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
});
return claims;
}
private string GetEncrpyedAccessToken(string accessToken)
{
return SimpleStringCipher.Instance.Encrypt(accessToken, AppConsts.DefaultPassPhrase);
}
}
}
I am getting a reasonable loginResult. And PasswordSignInAsync method returns with success. At that point I conclude the sign in process is OK. But after when I check User.Identity. I see it is null. Same is valid for the SignInAsync method.All I wanna do is sign-in the user only using the remote services. Thank you all..
I solved the problem as given below:
Change the httpost login method in AccountController of Web.Mvc application as below
[HttpPost]
[UnitOfWork]
public virtual async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "")
{
var claims = GetClaims(loginModel.UsernameOrEmailAddress, loginModel.Password);
if (claims == null)//giriş yapılamadı
{
return Json(new AjaxResponse { TargetUrl = "" });
}
else
{
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name,
ClaimTypes.Role);
foreach (var claim in claims)
{
identity.AddClaim(new Claim(claim.type, claim.value));
}
//AbpSession.UserId=18;
//// Authenticate using the identity
//var principal = new ClaimsPrincipal(identity);
//await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties { IsPersistent = true });
//bool chk = User.Identity.IsAuthenticated;
////bool bak = User.Identity.IsAuthenticated;
//bool bak2 = User.IsInRole("Admin");
//return RedirectToAction("Index", "Home");
await _signInManager.SignInAsync(identity, loginModel.RememberMe);
await UnitOfWorkManager.Current.SaveChangesAsync();
bool bak = User.Identity.IsAuthenticated;
var bakl = AbpSession.UserId;
}
returnUrl = NormalizeReturnUrl(returnUrl);
if (!string.IsNullOrWhiteSpace(returnUrlHash))
{
returnUrl = returnUrl + returnUrlHash;
}
return Json(new AjaxResponse { TargetUrl = returnUrl });
}
Create GetClaims method in AccountController of Web.Mvc application
protected List<ClaimRootObject> GetClaims(string UserName, string Password)
{
using (var client = new HttpClient())
{
string reqString = "http://localhost:21021/api/" + "TokenAuth/GetClaims/GetClaims?UserName=" + UserName + "&password=" + Password + "&TenantName=Default";
//string reqString = "http://localhost:81/api/TokenAuth/GetClaims/GetClaims?UserName=admin&password=123qwe&TenantName=TSEDergi";
HttpResponseMessage response = client.GetAsync(reqString).Result; // Blocking call!
if (response.IsSuccessStatusCode)
{
// Get the response
var JsonString = response.Content.ReadAsStringAsync();
// Deserialise the data (include the Newtonsoft JSON Nuget package if you don't already have it)
//List<Claim> deserialized = JsonConvert.DeserializeObject<List<Claim>>(JsonString.Result);
List<ClaimRootObject> deserialized = JsonConvert.DeserializeObject<List<ClaimRootObject>>(JsonString.Result);
if (deserialized != null)
{
return deserialized;
}
}
else
{
}
}
return null;
}
Create the required objects
public class ClaimRootObject
{
public string issuer { get; set; }
public string originalIssuer { get; set; }
public Properties properties { get; set; }
public Subject subject { get; set; }
public string type { get; set; }
public string value { get; set; }
public string valueType { get; set; }
}
public class Properties
{
}
public class Subject
{
public string authenticationType { get; set; }
public bool isAuthenticated { get; set; }
public object actor { get; set; }
public object bootstrapContext { get; set; }
public List claims { get; set; }
public object label { get; set; }
public string name { get; set; }
public string nameClaimType { get; set; }
public string roleClaimType { get; set; }
}
And last step, modify your startup class of Web.Mvc project to enable cookie authentication.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// MVC
services.AddMvc(
options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute())
);
#region cookieAuthentication
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
#endregion cookieAuthentication
IdentityRegistrar.Register(services);
AuthConfigurer.Configure(services, _appConfiguration);
services.AddScoped();
services.AddSignalR();
// Configure Abp and Dependency Injection
return services.AddAbp(
// Configure Log4Net logging
options => options.IocManager.IocContainer.AddFacility(
f => f.UseAbpLog4Net().WithConfig("log4net.config")
)
);
}
That's all. Then you can log in a user into the application using only remote services..

Replace url premeters to path based prameter

I have the following controller which accepts an optional "page" parameter.
Right now my URL would look something like mysite.com/pittsburgh-listings?page=2
I want the urls to look like this instead, how can I achieve this?
mysite.com/pittsburgh-listings/2
mysite.com/pittsburgh-listings/3
etc..
My controller
#Controller
public class CityController {
private static final int BUTTONS_TO_SHOW = 5;
private static final int INITIAL_PAGE = 0;
private static final int INITIAL_PAGE_SIZE = 40;
private static final int[] PAGE_SIZES = { 5, 10, 20, 40 };
private AdService adService;
public CityController(AdService adService) {
this.adService = adService;
}
#RequestMapping(value = "/{city:[\\w'-]+}-listings", method = RequestMethod.GET)
public String city(#PathVariable("city") String city, Model model, #RequestParam("page") Optional<Integer> page) {
Database db = new Database();
model.addAttribute("city", city.replace("-", " "));
System.out.println(city.replace("-", " "));
// List<Ad> ads = adService.getPage(1, city.replace("-", " "));
// model.addAttribute("ads", ads);
int evalPageSize = INITIAL_PAGE_SIZE;
int evalPage = (page.orElse(0) < 1) ? INITIAL_PAGE : page.get() - 1;
Long cityId = null;
try {
cityId = db.getCityId(city.replace("-", " "));
} catch (Exception e) {
e.printStackTrace();
}
Page<Ad> ads = adService.findAllPageable(new PageRequest(evalPage, evalPageSize, Sort.Direction.DESC, "id"),
cityId);
System.out.println("Ads: " + ads.getSize());
Pager pager = new Pager(ads.getTotalPages(), ads.getNumber(), BUTTONS_TO_SHOW);
model.addAttribute("ads", ads);
model.addAttribute("selectedPageSize", evalPageSize);
model.addAttribute("pageSizes", PAGE_SIZES);
model.addAttribute("pager", pager);
return "city";
}
}
You can change method signature as follows:
#RequestMapping(value = {"/{city:[\\w'-]+}-listings", "/{city:[\\w'-]+}-listings/{page}"}, method = RequestMethod.GET)
public String city(#PathVariable("city") String city, #PathVariable Optional<Integer> page, Model model) {
// ...
}
In order to map two endpoints (with and without page) in the same controller method and using Java 8 Optional to get page value.

Not able to access Request.Headers in BeginExecuteCore() method of Basecontroller MVC4

Can any one please help me? I am trying to implement localization in my mvc 4 WebApi application. I want to show the culture specific pages to the user on the basis of
"User-Locale" passed in the Request headers.
What I have done is, I am having a LinkedAccountModel class as shown below -
public class LinkedAccountModel
{
public string Id { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "DomainNameRequired")]
[DataType(DataType.Password)]
[Display(Name = "DomainName", ResourceType = typeof(LanguageResources.Resource))]
public string DomainName { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "UserNameRequired")]
[Display(Name = "UserName", ResourceType = typeof(LanguageResources.Resource))]
public string UserName { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "PasswordRequired")]
[DataType(DataType.Password)]
[Display(Name = "Password", ResourceType = typeof(LanguageResources.Resource))]
public string Password { get; set; }
[Required(ErrorMessageResourceType = typeof(LanguageResources.Resource), ErrorMessageResourceName = "ServerNameRequired")]
[Display(Name = "ServerName", ResourceType = typeof(LanguageResources.Resource))]
public string ServerName { get; set; }
[Required]
public long UserId { get; set; }
}
========================================================================
With this, I am having an ExchangeAccountSetupController which uses this model. This controller is implemented by the BaseController. My ExchangeAccountSetupController looks like as follows-
public class ExchangeAccountSetupController : BaseController
{
private PersistenceManagerAsync _persistenceManager;
public async Task<ActionResult> New(string sessionToken)
{
if (string.IsNullOrEmpty(sessionToken))
{
ViewBag.Title = LanguageResources.Resource.AccountConfigurationFailed;
ViewBag.ErrorMessage = LanguageResources.Resource.UnableToProcessRequest;
return View("Message");
}
_persistenceManager = new PersistenceManagerAsync(null);
var token = await _persistenceManager.RetrieveAsync<SessionToken>(string.Format("{0}|{1}", sessionToken.Substring(0, 10), sessionToken));
if (token == null)
{
ViewBag.Title = LanguageResources.Resource.AccountConfigurationFailed;
ViewBag.ErrorMessage = LanguageResources.Resource.UnableToProcessRequest;
return View("Message");
}
_persistenceManager = new PersistenceManagerAsync(token);
var user = new User { UserId = token.UserId };
var linkedAccount = await LinkedAccountManager.RetrieveLinkedAccount(_persistenceManager, user, "Exchange");
var linkedAccountModel = new LinkedAccountModel { UserId = token.UserId };
var existingUser = await _persistenceManager.RetrieveAsync<User>(user.PartitionKey, user.RowKey);
if (linkedAccount != null)
{
ViewBag.Title = LanguageResources.Resource.ChangePassword;
linkedAccountModel.DomainName = linkedAccount.DomainName;
linkedAccountModel.UserName = linkedAccount.UserName;
if (!string.IsNullOrEmpty(linkedAccount.Url))
linkedAccountModel.ServerName = new Uri(linkedAccount.Url).Host;
return View("New", linkedAccountModel);
}
ViewBag.Title = LanguageResources.Resource.ConfigureNewExchangeAccount; //default title.
return View("New", linkedAccountModel);
}
========================================================================
My BaseController looks like as follows -
public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
string currentLocale = string.Empty;
if (Request.Headers["User-Locale"] == null || string.IsNullOrEmpty(Request.Headers["User-Locale"]))
currentLocale = "en-US";
else
currentLocale = Request.Headers["User-Locale"];
// Modify current thread's cultures
string[] localeKeys = currentLocale.Split('-');
if (localeKeys[0].Equals("en"))
currentLocale = "en-US";
else if (localeKeys[0].Equals("nl"))
currentLocale = "nl-NL";
else
currentLocale = "en-US";
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(currentLocale);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
return base.BeginExecuteCore(callback, state);
}
}
========================================================================
My client application is in Dotnet only. I am sending a request to the "ExchangeAccountSetupController" controller's New() Action.
Here is the client application code where I am adding headers in my HttpClient Request-
var client = new HttpClient();
client.Timeout = new TimeSpan(1, 1, 1);
client.DefaultRequestHeaders.Add("User-Locale", "nl-NL");
var webResponse = httpClient.GetAsync(RestServiceUrl.GetLinkedAccountProviderUrl(accountProviderName)).Result;
if (webResponse.StatusCode != HttpStatusCode.OK)
return null;
var url = JsonConvert.DeserializeObject<string>(webResponse.Content.ReadAsStringAsync().Result);
return url;
My problem is that whenever I send a request from my client, the request reached to BaseController successfully.But I cannot access that "User-Locale" in the current Request object under BeginExecuteCore() method. I cannot access the "User-Locale" header from the Request object. I did not get any thing in Request.Headers["User-Locale"].It give me null.
Please tell me if I am doing anything wrong.Even I am not sure whether I can access that header under BeginExecuteCore() method or not .Any suggestions are highly appreciated.
There is no User-Locale header defined in HTTP. You are probably looking for the Accept-Language header.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
From MVC Web API you can get a hold of it with
Request.Headers.AcceptLanguage.
You can also get a parsed list of languages with this property
HttpContext.Current.Request.UserLanguages
Please note that the list is NOT sorted, contrary to what the documentation says.
http://msdn.microsoft.com/en-us/library/system.web.httprequest.userlanguages(v=vs.110).aspx

Resources