locked
[Identity + MVC] Get current user in .cshtml file RRS feed

  • Question

  • User-1370514677 posted

    Hi everyone,

    I'm trying to get current user name in a .cshtml file :

    Message.cs

    using System.ComponentModel.DataAnnotations;
    
    namespace Blog.Models
    {
        public class Message
        {
            public int Id { get; set; }
            [Required]
            public User Author { get; set; }
            [Required]
            [StringLength(240)]
            public string Text { get; set; }
        }
    }

    User.cs

    using Microsoft.AspNetCore.Identity;
    
    namespace Blog.Models
    {
        public class User : IdentityUser
        {}
    }

    Index.cshtml

    @foreach (var message in (List<Message>)ViewData["message_list"])
    {
        <div class="message_item">
            <p>@message.Author</p>
            <p>@message.Text</p>
    
            <div class="message_controls"> // This is the div to hide if @message.Author is not the same as the current user
                <a asp-controller="Message" asp-action="EditMessage" asp-route-id="@message.Id">Modifier</a>
                <a asp-controller="Message" asp-action="DeleteMessage" asp-route-id="@message.Id">Supprimer</a>
            </div>
        </div>
    }

    So, my wish is to show the div "message_controls" only if @message.Author matches with the current user.

    I've tried :

    @if(message.Author == User.Identity.Name) // Doesn't work
    @if(message.Author.UserName == User.Identity.Name) // Throws an error.

    But it doesn't work as User.identity.Name will return a string and the second option throws an Error.

    Thanks in advance for your help

    Monday, December 28, 2020 1:35 PM

All replies

  • User475983607 posted

    What is the error message?

    Monday, December 28, 2020 2:09 PM
  • User-1370514677 posted

    Hi @mgebhard,

    I get :

    NullReferenceException: Object reference not set to an instance of an object.
    
        AspNetCore.Views_Home_Index.<ExecuteAsync>b__24_1() in Index.cshtml
    
                            @if(message.Author.UserName == User.Identity.Name)
    

    Monday, December 28, 2020 2:40 PM
  • User475983607 posted

    The null exception is the most common error in programming.  The first step is using standard debugging tools to determine what is null.  

    https://docs.microsoft.com/en-us/visualstudio/debugger/?view=vs-2019

    I assume the Author property is null.  The error happens when trying to access UserName form the null Author property.  You'll need to review/debug the code that sets Author property and figure out why the property is null.

    Monday, December 28, 2020 3:29 PM
  • User-1370514677 posted

    mgebhard

    https://docs.microsoft.com/en-us/visualstudio/debugger/?view=vs-2019

    Thanks but I'm more a CLI guy and use VS Code and dotnet CLI commands.

    As a consequence, I implemented my own debugging output inside my controller :

    using System.Threading.Tasks;
    using Blog.Data;
    using Blog.Models;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Blog.Controllers
    {
        public class MessageController : Controller
        {
            private readonly AppDbContext _context;
            private readonly UserManager<User> _usermanager;
            public MessageController(AppDbContext context, UserManager<User> usermanager)
            {
                _context = context;
                _usermanager = usermanager;
            }
            
            [HttpGet]
            public IActionResult PublishMessage()
            {
                if(User.Identity.IsAuthenticated)
                    return View();
                else
                    return RedirectToAction("Signin", "User");
            }
    
            [HttpPost]
            public async Task<IActionResult> PublishMessage(Message message)
            {
                /*if(!ModelState.IsValid)
                    return View(message);*/
    
                var current_user = await _usermanager.GetUserAsync(User);
                if(current_user == null)
                    return View(message);
    
                var new_message = new Message{
                    Author = current_user,
                    Text = message.Text
                };
    
                System.Console.WriteLine("== PUBLISH MESSAGE ==");
    
                System.Console.WriteLine("Message Author = " + new_message.Author);
                System.Console.WriteLine("Message Text = " + new_message.Text);
                
                _context.Add(new_message);
                var result = await _context.SaveChangesAsync();
    
                return RedirectToAction("Index", "Home");
            }
    [HttpGet] public async Task<IActionResult> DeleteMessage(int Id) { /*if(!User.Identity.IsAuthenticated) return RedirectToAction("Index", "Home");*/ var message_to_delete = await _context.Message.FindAsync(Id); var current_user = await _usermanager.GetUserAsync(User); System.Console.WriteLine("== DELETE MESSAGE =="); System.Console.WriteLine("Message author = " + message_to_delete.Author); System.Console.WriteLine("Current user = " + current_user); if(message_to_delete.Author == current_user) { System.Console.WriteLine("=> Will remove message n°" + message_to_delete.Id); _context.Remove(message_to_delete); await _context.SaveChangesAsync(); } return RedirectToAction("Index", "Home"); } } }

    I obtain the following output :

    == PUBLISH MESSAGE == // LOGGED IN AS test@mail.com
    Message Author = test@mail.com
    Message Text = Hello, this is a test with test@mail.com
    == DELETE MESSAGE == // LOGGED IN AS test@mail.com
    Message author = test@mail.com
    Current user = test@mail.com
    => Will remove message n°1
    == PUBLISH MESSAGE == // LOGGED IN AS test@mail.com
    Message Author = test@mail.com
    Message Text = Hello, this is another test with test@mail.com
    == DELETE MESSAGE == // LOGGED OUT
    Message author = // Why no author is available for the same previous message ?
    Current user = // No output which is OK because user is logged out
    => Will remove message n°2

    Monday, December 28, 2020 6:04 PM
  • User1120430333 posted

    Thanks but I'm more a CLI guy and use VS Code and dotnet CLI commands.

    You don't seem to understand what the error message is telling you.

    It's OO 101 of class vs object vs instance. In order for a object to live in memory, which means the object exist, the class must be instanced into on object so that it lives in memory.

    If the object is never instanced, then it is a null valued object, it doesn't exist in memory and any code that tries to access or reference a null valued object  will cause the exception to be thrown. 

    Class vs Object vs Instance | Alfred's Computing Weblog (wordpress.com)

    .NET or Java it makes no difference. OO is OO.

    So you're going to have to use the Visual Stuido Debugger, set a breakpoint and start single stepping the code, until you hit the line that is throwing the exception. Then you will need to find out what object on the line is a null valued object by using Visual Stuido Quickwatch. You then need to find out why the object is a null valued object when code tries to use the object.

    Wednesday, December 30, 2020 7:37 AM
  • User475983607 posted

    valenciano8

    Thanks but I'm more a CLI guy and use VS Code and dotnet CLI commands.

    As a consequence, I implemented my own debugging output inside my controller :

    Your response makes little sense.  CLI are command line utilities.  Debuggers are tools within a dev toolchain that typically allow developers to stop execution and view state.  You are writing logs to the console which is fine and the approach I've used for years but the logs are written during runtime.  The log you've shown indicates the user is logged out so of course there's no Author.

    I recommend installing a debugger so you can single step through the code as the logic/design shown is rather confusing.  As written the code can attempt to delete a message that does not belong to the current user and the action allow anonymous users which is odd.

    Wednesday, December 30, 2020 2:02 PM
  • User753101303 posted

    Hi,

    Seems related to Loading Related Data - EF Core | Microsoft Docs

    Try for example somethhing such:

    var message_to_delete = await _context.Message.Include(m=>m.Author).SingleAsync(m=>m.Id==Id);

    Edit: if coming from EF6, a likely common catch is that lazy loading was enabled by default which is not the case in ASP.NET EF Core.

    Wednesday, December 30, 2020 3:31 PM