باستخدام عضوية وملف تعريف ASP .NET مع MVC ، كيف يمكنني إنشاء مستخدم وتعيينه على httpcontext.current.user؟

StackOverflow https://stackoverflow.com/questions/2547290

سؤال

لقد قمت بتطبيق كائن ملف تعريف مخصص في الكود كما هو موضح من قبل جويل هنا:

كيفية تعيين قيم الملف الشخصي؟

لا يمكنني تشغيله عندما أقوم بإنشاء مستخدم جديد. عندما أفعل هذا:

Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");

يتم إنشاء المستخدم وإضافته إلى دور في قاعدة البيانات ، ولكن HttpContext.Current.User لا تزال فارغة ، و Membership.GetUser() إرجاع NULL ، لذلك هذا (من رمز جويل) لا يعمل:

static public AccountProfile CurrentUser
{
    get { return (AccountProfile)
                     (ProfileBase.Create(Membership.GetUser().UserName)); }
}

AccountProfile.CurrentUser.FullName = "Snoopy";

لقد حاولت الاتصال Membership.GetUser(userName) وتعيين خصائص الملف الشخصي بهذه الطريقة ، ولكن تظل خصائص المجموعة فارغة ، والاتصال AccountProfile.CurrentUser(userName).Save() لا يضع أي شيء في قاعدة البيانات. لقد حاولت أيضًا الإشارة إلى أن المستخدم صالح وتسجيل الدخول ، عن طريق الاتصال Membership.ValidateUser, FormsAuthentication.SetAuthCookie, ، وما إلى ذلك ، لكن المستخدم الحالي لا يزال فارغًا أو مجهولًا (اعتمادًا على حالة ملفات تعريف الارتباط الخاصة بمستعرضي).

حل (تم تحريره ، انظر أدناه): استنادًا إلى شرح فرانسي بينوف وبعض التجارب ، اكتشفت المشكلة. لن تعمل رمز جويل والتغيرات التي جربتها إلا مع ملف تعريف موجود. إذا لم يكن هناك ملف تعريف ، ProfileBase.Create(userName) سيعود كائنًا فارغًا جديدًا في كل مرة يطلق عليها ؛ يمكنك تعيين خصائص ، لكنها لن "تلتصق" لأنه يتم إرجاع مثيل جديد في كل مرة يمكنك الوصول إليها. جلسة HttpContext.Current.User إلى جديد GenericPrincipal إرادة يعطيك كائن مستخدم ، ولكن ليس كائن ملف تعريف ، و ProfileBase.Create(userName) و HttpContext.Current.Profile سيظل يشير إلى كائنات جديدة فارغة.

إذا كنت ترغب في إنشاء ملف تعريف لمستخدم تم إنشاؤه حديثًا في نفس الطلب ، فأنت بحاجة إلى الاتصال HttpContext.Current.Profile.Initialize(userName, true). يمكنك بعد ذلك ملء الملف الشخصي المهيئ وحفظه ، وسيكون متاحًا بناءً على الطلبات المستقبلية بالاسم ، لذلك سيعمل رمز جويل. انا فقط استخدام HttpContext.Current.Profile داخليًا ، عندما أحتاج إلى إنشاء/الوصول إلى الملف الشخصي فور إنشاء. في أي طلبات أخرى ، أستخدمها ProfileBase.Create(userName), ، وقد كشفت فقط هذا الإصدار كعالوب.

لاحظ أن Franci صحي عبر رمز جويل بناءً على الطلب اللاحق. ما ألقاه هو أن الأدوار يمكن الوصول إليها على الفور عند إنشاء المستخدم دون أي تهيئة ، ولكن ملف التعريف ليس كذلك.

رمز حسابي الجديد:

public static AccountProfile CurrentUser
{
    get
    {
        if (Membership.GetUser() != null)
            return ProfileBase.Create(Membership.GetUser().UserName) as AccountProfile;
        else
            return null;
    }
}

internal static AccountProfile NewUser
{
    get { return System.Web.HttpContext.Current.Profile as AccountProfile; }
}

إنشاء مستخدم جديد:

MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();

الوصول اللاحق:

if (Membership.ValidateUser(userName, password))
{
    string name = AccountProfile.CurrentUser.FullName;
}

علاوة على ذلك ، بفضل فرانسي لشرح دورة حياة المصادقة - أنا أتصل بـ Formsauthentication.SetAuthCookie في وظيفة التحقق من الصحة ، لكنني أعيد منطقيًا للإشارة إلى النجاح ، لأن المستخدم.

مراجعة: أنا مغفل. يعمل التفسير أعلاه في الحالة الضيقة ، ولكنه لا يحل المشكلة الأساسية: يرجع استدعاء CurrentUser إلى مثيل جديد للكائن في كل مرة ، سواء كان ملف تعريف موجود أم لا. لأنه تم تعريفه على أنه خاصية ، لم أكن أفكر في هذا ، وكتبت:

AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();

الذي (بالطبع) لا يعمل. يجب أن يكون:

AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();

إنه خطأي الخاص في التغلب على هذه النقطة الأساسية تمامًا ، لكنني أعتقد أن إعلان CurrentUser كخاصية يعني أنه كائن يمكن معالجته. بدلاً من ذلك ، يجب إعلانه باسم GetCurrentUser().

هل كانت مفيدة؟

المحلول

إنشاء مستخدم يضيفه فقط إلى قائمة المستخدمين. ومع ذلك ، فإن هذا لا يصادق أو يسمح للمستخدم الجديد للطلب الحالي. تحتاج أيضًا إلى مصادقة المستخدم في سياق الطلب الحالي أو للطلبات اللاحقة.

Membership.ValidateUser سوف يتحقق فقط من صحة بيانات الاعتماد ، ولكنه لا يصادق المستخدم للطلبات الحالية أو اللاحقة. FormsAuthentication.SetAuthCookie سيقوم بتعيين تذكرة المصادقة في دفق الاستجابة ، لذلك سيتم المصادقة على الطلب التالي ، لكنه لا يؤثر على حالة الطلب الحالي.

أسهل طريقة لمصادقة المستخدم هي الاتصال FormsAuthentication.RedirectFromLoginPage (على افتراض أنك تستخدم مصادقة النماذج في تطبيقك). ومع ذلك ، فإن هذا الأمر قد يتسبب بالفعل في طلب HTTP جديد ، والذي سيصادق المستخدم.

بدلاً من ذلك ، إذا كنت بحاجة إلى متابعة منطقك لمعالجة الطلب الحالي ، ولكن تريد مصادقة المستخدم ، يمكنك إنشاء ملف GenericPrincipal, ، قم بتعيين هوية المستخدم الجديد وقم بتعيين ملف HttpContext.User لهذا المدير.

نصائح أخرى

سوف تواجه مشاكل مع هذا النهج إذا قمت بتمكين عدم الكشف عن هويته. بدلاً من العضوية. getuser (). اسم المستخدم ، أود أن أقترح استخدام httpcontext.profile.username.

مثله...

private UserProfile _profile;
private UserProfile Profile
{
    get { return _profile ?? (_profile = (UserProfile)ProfileBase.Create(HttpContext.Profile.UserName)); }
}

طرف القبعة: sqlprofileprovider - هل يمكنك استخدام ملف التعريف. getProfile () في مشروع؟

بادئ ذي بدء ، شكرًا @jeremy على مشاركة النتائج التي توصلت إليها. لقد ساعدتني في الذهاب في الاتجاه الصحيح. ثانياً ، آسف لصياغة هذا المنشور القديم. نأمل أن يساعد هذا شخص ما في ربط النقاط.

كانت الطريقة التي حصلت بها أخيرًا على هذا العمل هي استخدام الطريقة الثابتة التالية داخل فصل ملف التعريف الخاص بي:

internal static void InitializeNewMerchant(string username, Merchant merchant)
{
    var profile = System.Web.HttpContext.Current.Profile as MerchantProfile;
    profile.Initialize(username, true);
    profile.MerchantId = merchant.MerchantId;
    profile.Save();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top