I also thought about directly sending those attributes from the Controller but it's the same issue (current user's attributes are not accesible from what I've tried)
But this won't work as I want to access the current user's attributes
Do you mean that "@User.Identity.UserName" can't get the name of the currently logged in user?If you want to get other information about the current logged in user in ASP.NET Core, you can
refer to this link.
Best Regards,
YihuiSun
.NET forums are moving to a new home on Microsoft Q&A, we encourage you to go to Microsoft Q&A for .NET for posting new questions and get involved today.
Do you mean that "@User.Identity.UserName" can't get the name of the currently logged in user?
I meant I want to access the Avatar attribute, take a look at my model here :
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Identity;
namespace Blog.Models
{
public class User : IdentityUser
{
// Identity Fields
// Customized fields
[Required]
[Display(Name = "Name : ")]
public string Name { get; set; }
[Required]
[Display(Name = "Surname : ")]
public string Surname { get; set; }
public byte[] Avatar { get; set; }
}
}
I can't just use @User.Avatar inside a .cshtml file.
What I've tried to do is to create a "GetCurrentUserAvatar()" method that returns the byte array from UserController into HomeController where I return the Index() view.
UserController.cs
[HttpGet]
[Authorize]
public async Task<byte[]> GetCurrentUserAvatar()
{
var current_user = await _usermanager.GetUserAsync(User);
return current_user.Avatar;
}
HomeController.cs
using Microsoft.AspNetCore.Mvc;
namespace Blog.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public IActionResult Index()
{ // Call of GetCurrentUserAvatar() should be here // But it is not a good MVC principle from what I've seen on the web
return View();
}
}
}
Assuming you are using the ASP.NET Core Identity for the authentication...
User.Identity returns the ClaimsIdentity. If you want get the information from the ClaimsIdentity, therefore, such information must be registered in the ClaimsIdentity, In additoin you will have to define a extension method to obtain the information from
the ClaimsIdentity.
As a byte array cannot be registered in the ClaimsIdentity, you will have to convert the byte array to base64-encoded string and to register the encoded string. But keep in mind that it will probably make the authentication cookie very long and may result
in exceeding the limit.
.NET forums are moving to a new home on Microsoft Q&A, we encourage you to go to Microsoft Q&A for .NET for posting new questions and get involved today.
I assume you are able to save the user's avatar as a byte[] in the database. The next step is creating an action to return the image.
I added a content type to the custom user fields so the user can upload different image types.
public class ApplicationUser : IdentityUser
{
public byte[] Avatar { get; set; }
public string AvatarContentType { get; set; }
}
The action gets the current user's avatar. A default image is shown if the user have not uploaded an avatar. The default image is in the wwwroot/images folder. Find a default image you like and copy it to wwwroot/images with the name; no-image.png.
[Authorize]
public class AvatarController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IWebHostEnvironment _webHostEnvironment;
public AvatarController(UserManager<ApplicationUser> userManager,
IWebHostEnvironment webHostEnvironment)
{
_userManager = userManager;
_webHostEnvironment = webHostEnvironment;
}
// GET: AvatarController
public async Task<ActionResult> IndexAsync()
{
var user = await _userManager.GetUserAsync(User);
//Return a default image is the user does not an image on file.
if(user.Avatar == null || user.Avatar.Length == 0)
{
string path = System.IO.Path.Combine(_webHostEnvironment.WebRootPath, "images", "no-image.png");
System.IO.FileStream avatar = System.IO.File.OpenRead(path);
return File(avatar, "image/png");
}
return File(user.Avatar, user.AvatarContentType);
}
}
If I use /User/GetCurrentUserAvatar manually I get a full string.
If I just look at what the browser is rendering, it is just a blank image :(
Base64 encoded images are passed to the View like any model. The View contains the markup to embed the image. Your last posting is an approach that you fabricated. It is not an approach you'll found in any reference documentation because it is does not
work. Also, base64 encoding increases the image size by 1/3.
Is there some reason why you did not follow my example?
Um No. You managed to brake the code. Now there's no default image. Every user must upload a png otherwise the request will result in a 404.
valenciano8
// Yet I'm not sure that hard coding URLs is a good way to proceed
Can you clarify what the issue is? This one URL handles every authenticated application user. I suppose you could turn it into a ViewComponent but I still do not understand the problem.
Probably you do not want the web server to fetch the image from the database server every time a user requests a page. So you will consider to include a cache control in the action method so that the image will be stored in the Cache of browser for a certain
period of time. It will work for the time being.
However, some time later a user will change his avatar by uploading a new image. At that time the user does not want to see the old avatar on his page. But it is not good idea to expect a user to delete the cache. You will have to consider how to cope with
it.
Member
10 Points
73 Posts
[Identity] Use current user's attributes in CSHTML
Jan 16, 2021 10:25 PM|valenciano8|LINK
Hi everyone,
I've been searching the web for a way to use Identity current user's attributes with Razor syntax for hours and couldn't really find an answer.
With a foreach loop I would use a
But this won't work as I want to access the current user's attributes
Any Idea ?
I also thought about directly sending those attributes from the Controller but it's the same issue (current user's attributes are not accesible from what I've tried)
Thanks in advance for your help
Contributor
2690 Points
774 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 18, 2021 10:07 AM|YihuiSun|LINK
Hi valenciano8,
Do you mean that "@User.Identity.UserName" can't get the name of the currently logged in user?If you want to get other information about the current logged in user in ASP.NET Core, you can refer to this link.
Best Regards,
YihuiSun
Member
10 Points
73 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 18, 2021 06:04 PM|valenciano8|LINK
Hi @YihuiSun,
Thank you for your answer ;)
I meant I want to access the Avatar attribute, take a look at my model here :
I can't just use @User.Avatar inside a .cshtml file.
What I've tried to do is to create a "GetCurrentUserAvatar()" method that returns the byte array from UserController into HomeController where I return the Index() view.
UserController.cs
HomeController.cs
So how to proceed ? :(
Member
330 Points
232 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 02:54 AM|SurferOnWww|LINK
Assuming you are using the ASP.NET Core Identity for the authentication...
User.Identity returns the ClaimsIdentity. If you want get the information from the ClaimsIdentity, therefore, such information must be registered in the ClaimsIdentity, In additoin you will have to define a extension method to obtain the information from the ClaimsIdentity.
As a byte array cannot be registered in the ClaimsIdentity, you will have to convert the byte array to base64-encoded string and to register the encoded string. But keep in mind that it will probably make the authentication cookie very long and may result in exceeding the limit.
Contributor
2690 Points
774 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 05:21 AM|YihuiSun|LINK
Hi valenciano8,
Additional claims can be added to ASP.NET Core Identity by using the IUserClaimsPrincipalFactory<T> interface.
You can customize a class called AdditionalUserClaimsPrincipalFactory and override GenerateClaimsAsync:
AdditionalUserClaimsPrincipalFactory
View
Startup
Here is the result.
Best Regards,
YihuiSun
Member
10 Points
73 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 12:01 PM|valenciano8|LINK
Hi @YihuiSun,
Again, thanks a lot for your very detailed answer !
I appreciate the help you're providing me with, yet I don't really understand how using Claims is going to help me get through my issue ?
Because from what I understand, claims are mainly used for authentication : Claims-based authorization in ASP.NET Core | Microsoft Docs
Isn't there an easier or more conventional way to simply access whatever attributes of current user ?
All-Star
52971 Points
23574 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 05:12 PM|mgebhard|LINK
I assume you are able to save the user's avatar as a byte[] in the database. The next step is creating an action to return the image.
I added a content type to the custom user fields so the user can upload different image types.
The action gets the current user's avatar. A default image is shown if the user have not uploaded an avatar. The default image is in the wwwroot/images folder. Find a default image you like and copy it to wwwroot/images with the name; no-image.png.
HTML implementation
Member
10 Points
73 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 06:42 PM|valenciano8|LINK
Hi @mgebhard,
Thank you for your answer.
So your point is to return the avatar directly from the Controller.
But I already have a GetCurrentUserAvatar method in my UserController, I've changed it so that it returns a Base64String :
(see [Avatar picture] How to store avatar picture and link it to Identity | The ASP.NET Forums)
I then modified my HTML code :
If I use /User/GetCurrentUserAvatar manually I get a full string.
If I just look at what the browser is rendering, it is just a blank image :(
All-Star
52971 Points
23574 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 07:20 PM|mgebhard|LINK
No. Not really.
I followed your original design and stored the images as a byte array which is the same concept as a file on disk.
Base64 encoded images are passed to the View like any model. The View contains the markup to embed the image. Your last posting is an approach that you fabricated. It is not an approach you'll found in any reference documentation because it is does not work. Also, base64 encoding increases the image size by 1/3.
Is there some reason why you did not follow my example?
Member
10 Points
73 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 08:28 PM|valenciano8|LINK
Hi @mgebhard,
You were right it works !
I've simplified your code hereafter :
So basically what I just had to do was to :
Thanks !
All-Star
52971 Points
23574 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 19, 2021 08:56 PM|mgebhard|LINK
Um No. You managed to brake the code. Now there's no default image. Every user must upload a png otherwise the request will result in a 404.
Can you clarify what the issue is? This one URL handles every authenticated application user. I suppose you could turn it into a ViewComponent but I still do not understand the problem.
Member
330 Points
232 Posts
Re: [Identity] Use current user's attributes in CSHTML
Jan 20, 2021 03:25 AM|SurferOnWww|LINK
Probably you do not want the web server to fetch the image from the database server every time a user requests a page. So you will consider to include a cache control in the action method so that the image will be stored in the Cache of browser for a certain period of time. It will work for the time being.
However, some time later a user will change his avatar by uploading a new image. At that time the user does not want to see the old avatar on his page. But it is not good idea to expect a user to delete the cache. You will have to consider how to cope with it.