วิธีรับผู้ใช้ปัจจุบันและวิธีใช้คลาสผู้ใช้ใน MVC5


159
  • ฉันจะรับรหัสของผู้ใช้ที่เข้าสู่ระบบในปัจจุบันในMVC 5 ได้อย่างไร ฉันลองใช้คำแนะนำ StackOverflow แต่ดูเหมือนว่าไม่ใช่สำหรับ MVC 5
  • นอกจากนี้ MVC 5 แนวปฏิบัติที่ดีที่สุดในการมอบหมายสิ่งของให้กับผู้ใช้คืออะไร? (เช่นUserควรมีItems. ฉันควรเก็บผู้ใช้IdในItem? ฉันสามารถขยายUserชั้นเรียนที่มีList<Item>คุณสมบัตินำทาง?

ฉันกำลังใช้ "บัญชีผู้ใช้ส่วนบุคคล" จากเทมเพลต MVC

พยายามเหล่านี้:

'Membership.GetUser ()' เป็นโมฆะ


เพิ่มการอ้างอิงของสิ่งที่ฉันได้ลอง อันสุดท้ายคือ OK ใน MVC4 แต่ไม่ใช่ใน MVC5 นอกจากนี้ฉันต้องการแนวปฏิบัติที่ดีที่สุดของ "การใช้ผู้ใช้" :)
Adam Szabo

เมื่อคุณพูดว่าคุณกำลังใช้ MVC 5 คุณจะใช้อะไรในการเป็นสมาชิก OWin.Security?
Aron

"บัญชีผู้ใช้ส่วนบุคคล" จากเทมเพลต MVC
Adam Szabo

3
HttpContext.Current.User.Identity.Nameเป็นชื่อของผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน
Wiktor Zychla

1
วิธีการรับId ? ฉันต้องการกำหนดผู้ใช้ปัจจุบันให้กับItemเขาสร้าง แต่ไม่ได้ขึ้นอยู่กับชื่อผู้ใช้ (อาจมีการเปลี่ยนแปลง) มันไม่ทำงานโดยใช้วิธี 'HttpContext.Current' System.Web.HttpContextBase 'ไม่มีคำจำกัดความสำหรับ' ปัจจุบัน 'และไม่มีวิธีการขยาย' ปัจจุบัน 'ที่ยอมรับอาร์กิวเมนต์แรกของประเภท' System.Web.HttpContextBase '( คุณไม่มีคำสั่งที่ใช้หรืออ้างอิงประกอบ?) ` คุณแน่ใจหรือไม่ว่าทางออกของคุณสำหรับ MVC 5
Adam Szabo

คำตอบ:


313

หากคุณกำลังเขียนโปรแกรมใน ASP.NET MVC Controller ให้ใช้

using Microsoft.AspNet.Identity;

...

User.Identity.GetUserId();

มูลค่าการกล่าวขวัญว่าUser.Identity.IsAuthenticatedและUser.Identity.Nameจะทำงานโดยไม่ต้องเพิ่มusingคำสั่งดังกล่าวข้างต้น แต่GetUserId()จะไม่ปรากฏตัวหากปราศจากมัน

หากคุณอยู่ในคลาสอื่นที่ไม่ใช่คอนโทรลเลอร์ให้ใช้

HttpContext.Current.User.Identity.GetUserId();

ในเทมเพลตเริ่มต้นของ MVC 5 ID ผู้ใช้เป็น GUID ที่จัดเก็บเป็นสตริง

ยังไม่มีแนวปฏิบัติที่ดีที่สุด แต่พบข้อมูลที่มีค่าเกี่ยวกับการขยายโปรไฟล์ผู้ใช้:


9
การรับรองความถูกต้องของผู้ใช้และการอนุญาตได้เปลี่ยนไปสำหรับ ASP.NET MVC 5 ตอนนี้เป็นการตรวจสอบความถูกต้องตามการอ้างสิทธิ์ด้วยส่วนต่อประสานและแหล่งเก็บข้อมูลทั่วไปที่คุณสามารถใช้กับ EF หรือผู้ให้บริการอื่น ๆ เนื่องจากGetUserIdเป็นวิธีส่วนขยายที่เก็บไว้ที่ด้านล่างของAss_Start\IdentityConfig.csทุกที่ที่คุณต้องการใช้ถ้าในเนมสเปซที่แตกต่างกันคุณจะต้องตั้งค่าusing Microsoft.AspNet.Identityให้ส่วนขยายปรากฏให้เห็น
Anderson Matos

1
survey.UserId = Guid.Parse (User.Identity.GetUserId ());
NicoJuicy

หากฉันเพิ่มการอ้างอิงโดยใช้ผู้ใช้ยังคงขีดเส้นใต้สีแดง ทำไมถึงเป็นเช่นนี้?
Zapnologica

@Zapnologica: ลองสร้างโครงการใหม่อีกครั้งบางที VS IntelliSense อาจช้าไปหน่อย
Adam Szabo

5
หมายเหตุผู้ใช้จะใช้ได้เฉพาะในตัวควบคุมmsdn.microsoft.com/en-us/library/… (@Zapnologica คุณใช้มันนอกตัวควบคุมหรือไม่ลอง HttpContext.Current.User.Identity.GetUserId ();
Adween

28

ลองสิ่งที่ชอบ:

var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
var userManager = new UserManager<ApplicationUser>(store);
ApplicationUser user = userManager.FindByNameAsync(User.Identity.Name).Result;

ทำงานร่วมกับ RTM


11
มันกำหนดทริปฐานข้อมูลที่ไม่จำเป็น
Arash

3
@Arash แอปพลิเคชันควรจะรับวัตถุของผู้ใช้โดยไม่ต้องติดต่อฐานข้อมูลอย่างไร
fabspro

2
@Arash ไม่เป็นไรฉันเห็นสิ่งที่คุณหมายถึง ID สามารถดึงข้อมูลได้ด้วย User.Identity.GetUserId (); ไม่มีการเดินทางฐานข้อมูลใด ๆ
fabspro

จดจำด้วย mvc5 (ความเป็นสมาชิก 2): User.Identity.GetUserId () แตกต่างกับ id ในตาราง [AspNetUsers] ดังนั้นจาคอบอาร์โนลด์และร็อคจึงเป็นวิธีที่ถูกต้อง
เกรย์วูล์ฟ

ฉันสับสนเล็กน้อยกับคำตอบ ฉันได้รับประเภท UserStore ดูเหมือนจะไม่มีอยู่ในบริบทตัวควบคุมของฉัน ความคิดใด ๆ
Jhourlad Estrella

19

ถ้าคุณต้องการวัตถุ ApplicationUser ในหนึ่งบรรทัดของรหัส (ถ้าคุณมี ASP.NET Identity ล่าสุดติดตั้ง) ลอง:

ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

คุณจะต้องใช้คำสั่งต่อไปนี้:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

ไม่พบวัตถุสำหรับ <ApplicationUserManager>
Fandango68

7

การรับรหัสตรงไปตรงมาและคุณได้แก้ไขแล้ว

แม้ว่าคำถามที่สองของคุณจะเกี่ยวข้องกับอีกเล็กน้อย

ดังนั้นนี่คือสิ่งก่อนวางจำหน่ายทั้งหมดในขณะนี้ แต่ปัญหาทั่วไปที่คุณเผชิญคือที่ที่คุณขยายผู้ใช้ด้วยคุณสมบัติใหม่ (หรือคอลเล็กชันรายการในคำถามของคุณ)

ออกจากกล่องคุณจะได้รับไฟล์ที่เรียกว่าIdentityModelภายใต้โฟลเดอร์รุ่น (ในเวลาที่เขียน) ในนั้นคุณมีชั้นเรียนสองชั้น และApplicationUser ApplicationDbContextในการเพิ่มคอลเลกชันของItemsคุณคุณจะต้องแก้ไขApplicationUserคลาสเช่นเดียวกับที่คุณทำหากนี่เป็นคลาสปกติที่คุณใช้กับ Entity Framework ในความเป็นจริงถ้าคุณดูอย่างรวดเร็วภายใต้ประทุนคุณจะพบว่าคลาสที่เกี่ยวข้องกับตัวตนทั้งหมด (ผู้ใช้บทบาท ฯลฯ ... ) เป็นเพียง POCOs ตอนนี้พร้อมคำอธิบายประกอบข้อมูลที่เหมาะสมเพื่อให้พวกเขาเล่นกับ EF6 ได้ดี

ถัดไปคุณจะต้องทำการเปลี่ยนแปลงบางอย่างกับAccountControllerนวกรรมิกเพื่อให้มันรู้ว่าจะใช้ DbContext ของคุณ

public AccountController()
{
    IdentityManager = new AuthenticationIdentityManager(
    new IdentityStore(new ApplicationDbContext()));
}

ตอนนี้รับวัตถุผู้ใช้ทั้งหมดสำหรับผู้ใช้ที่เข้าสู่ระบบของคุณเป็นความลับเล็กน้อยที่จะซื่อสัตย์

    var userWithItems = (ApplicationUser)await IdentityManager.Store.Users
    .FindAsync(User.Identity.GetUserId(), CancellationToken.None);

บรรทัดนั้นจะทำงานให้เสร็จและคุณจะสามารถเข้าถึงได้ตามที่userWithItems.Itemsคุณต้องการ

HTH


ฉันไม่คิดว่าจะมีอะไรเหมือนเอกสารเผยแพร่ล่วงหน้าสำหรับทั้งหมดนี้ใช่ไหม
Derek Tomes

@Derek Tomes - ไม่ใช่ว่าฉันเคยเจอ ฉันคิดว่าเราจะต้องรอจนถึงวันที่ 13 พ.ย. สำหรับเอกสารจริง มันไม่ได้ยอดเยี่ยมที่จะซื่อสัตย์มีแม้แต่คำขอสำหรับคำแนะนำที่ดีกว่าที่ uservoice - aspnet.uservoice.com/forums/41199-general-asp-net/suggestions/ …
EightyOne Unite

ตกลง แต่ฉันจะไปยังตัวอย่างประเภทได้AccountControllerอย่างไร
ทำรัง

0

ฉันรู้สึกถึงความเจ็บปวดของคุณฉันกำลังพยายามทำสิ่งเดียวกัน ในกรณีของฉันฉันต้องการล้างผู้ใช้

ฉันได้สร้างคลาสคอนโทรลเลอร์พื้นฐานที่คอนโทรลเลอร์ทั้งหมดของฉันสืบทอดมา ในนั้นฉันจะแทนที่OnAuthenticationและตั้งค่าfilterContext.HttpContext.User to null

นั่นเป็นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้ ...

public abstract class ApplicationController : Controller   
{
    ...
    protected override void OnAuthentication(AuthenticationContext filterContext)
    {
        base.OnAuthentication(filterContext); 

        if ( ... )
        {
            // You may find that modifying the 
            // filterContext.HttpContext.User 
            // here works as desired. 
            // In my case I just set it to null
            filterContext.HttpContext.User = null;
        }
    }
    ...
}

0
        string userName="";
        string userId = "";
        int uid = 0;
        if (HttpContext.Current != null && HttpContext.Current.User != null
                  && HttpContext.Current.User.Identity.Name != null)
        {
            userName = HttpContext.Current.User.Identity.Name;              
        }
        using (DevEntities context = new DevEntities())
        {

              uid = context.Users.Where(x => x.UserName == userName).Select(x=>x.Id).FirstOrDefault();
            return uid;
        }

        return uid;

โปรดอย่าเพิ่งโพสต์รหัสโดยเฉพาะอย่างยิ่งไม่มีความคิดเห็นใด ๆ หากคุณอธิบายรหัสของคุณมันจะมีประโยชน์มากขึ้น
Ali Kanat

0

หากมีคนอื่นที่มีสถานการณ์เช่นนี้: ฉันกำลังสร้างการยืนยันอีเมลเพื่อลงชื่อเข้าใช้แอปของฉันเพื่อให้ผู้ใช้ของฉันไม่ได้ลงชื่อเข้าใช้ แต่ฉันใช้ด้านล่างเพื่อตรวจสอบอีเมลที่ป้อนในการเข้าสู่ระบบ

 ApplicationUser user = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindByEmail(Email.Text);

คุณจะต้องต่อไปนี้:

using Microsoft.AspNet.Identity;

และ

using Microsoft.AspNet.Identity.Owin;


0

นี่คือวิธีที่ฉันได้รับ AspNetUser Id และแสดงมันในหน้าแรกของฉัน

ฉันวางโค้ดต่อไปนี้ในวิธีการของ HomeController Index ()

ViewBag.userId = User.Identity.GetUserId();

ในหน้ามุมมองเพียงโทร

ViewBag.userId 

เรียกใช้โครงการและคุณจะเห็น userId ของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.