سؤال

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

الآن ، فإن توقيع طريقة التغيير التي يجب تجاوزها من قبل مزود مخصص هو:

public override bool ChangePassword(string username, string oldPassword, string newPassword)

لذا ، على الرغم من أنني أعرف المشكلة الدقيقة في كلمة المرور الجديدة التي يوفرها المستخدم ، إلا أنني غير قادر على عرضها على صفحة الويب لأنني لا أستطيع إلا إرجاع صحيح أو خطأ من هذه الطريقة والتحكم في كلمة مرور التغيير ثم يتولى ويقوم بالسيطرة السحر اعتمادا على قيمة الإرجاع المنطقية. يمكنني ربط OnChangePasswordError حدث ChangePassword التحكم في إظهار رسالة خطأ ثابتة ، أو يمكنني حتى إعداد FailureText خاصية عنصر التحكم هذا لبعض السلسلة المرمزة عند حدوث خطأ ، لكنني غير قادر على توفير للمستخدم ما هو الخطأ بالضبط في كلمة المرور التي قدموها.

protected void OnPasswordChangeError(object sender, EventArgs e)
        {
            throw new MembershipPasswordException("Tell user what exactly is wrong with the password they supplied");
        }

ال MembershipProvider الفصل لديه ValidatingPassword الحدث ، الذي أثير قبل تغيير كلمة المرور ، ويمكنني إلقاء استثناء هنا من خلال التحقق مما إذا كانت كلمة المرور تلبي المعايير ، ولكن لا يزال هذا الاستثناء لا يتم نقله إلى عنصر تحكم التغيير. فيما يلي رمز التحقق من صحة الحدث:

void MyMembershipProvider_ValidatingPassword(object sender, ValidatePasswordEventArgs e)
        {
           //if password not valid
           e.Cancel = true;
           e.FailureInformation = new MembershipPasswordException();
           e.FailureInformation;           
        }  

كيفية إرسال معلومات محددة من طريقة ChangePassword لفئة مزود العضوية إلى عنصر تحكم ChangePassword لعرض رسائل الخطأ الصحيحة غير الساكنة/غير الثابتة/المتشددين إلى المستخدم؟ هل هناك طريقة لتوصيل ValidatePassPasswordeventArgs إلى EventArgs في EventHandler لطريقة OnChangePassword حتى أتمكن من الحصول على FaintInformation في عنصر التحكم في تغيير WANGEPSPORD؟

من بحثي الأولي ، لا يبدو هذا ممكنًا. على الرغم من أنني أشعر أن فريق MS لن يتجاهل هذا ويجب أن يكون هناك طريقة.

بعض المؤشرات:

العضوية http://forums.asp.net/t/983613.aspx

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

المحلول

حسنًا ، لذلك اعتقدت أخيرًا حلًا بديلًا. إنه ليس أنظف ، لكن الشخص الوحيد الذي يمكنني التوصل إليه أو وجدته في أي مكان كان قريبًا مما كان ينبغي أن يميل افتراضيًا.

ملاحظة: لم يكن لدي خيار استمرار هذا في قاعدة بيانات أو ملف تعريف ارتباط.

لقد خلقت أ ChangePasswordNew الطريقة التي لها نفس سلوك MembershipProvider ChangePassword الطريقة ، ولكن إرجاع السلسلة بدلا من منطق. لذا فإن طريقتي الجديدة ستبدو هكذا:

public string ChangePasswordNew(string username, string oldPassword, string newPassword)
{
    //if password rules met, change password but do not return bool as MembershipProvider method does, 
    //return Success or the exact error for failure instead
    if(passwordChangeRequirementsMet == true)  
    {
        //change the password
        return "success";
    }
    else          
        return "exact reason why password cannot be changed";
}

الآن ، اشترك في onPasswordChanging حدث ChangePassword مراقبة:

protected void PasswordIsChanging(object sender, LoginCancelEventArgs e)
{
try
    {
      string response = Provider.ChangePasswordNew(username, currentPass, newPass);
      if(response != "success")
      {
        changePwdCtrl.FailureText = response;
      }
     else
    {
    //cancel call to the default membership provider method that will attempt to
    //change the password again. Instead, replicate the 'steps' of AttemptChangePassword(), 
    //an internal method of the ChangePassword control.
    //Performing all the steps instead of calling the method because just calling method
    //does not work for some reason

    e.Cancel = true;
    FormsAuthentication.SetAuthCookie(username, false);
    OnPasswordChanged(sender, e);

    MethodInfo successMethodInfo = changePwdCtrl.GetType().GetMethod("PerformSuccessAction",                                    BindingFlags.NonPublic | BindingFlags.Instance);
    successMethodInfo.Invoke(changePwdCtrl, new object[] { "", "", changePwdCtrl.NewPassword });
}
}
catch(Exception ex)
{
    LogException(ex);
    throw;
}

}

ملحوظة: في هذه الحالة ، إذا كان هناك خطأ في تغيير كلمة المرور ، فإن استجابة IE ليست "نجاح" ، مزود الميمبرز ChangePassword ستظل الطريقة ستستدعي وسيعود خطأ مرة أخرى. لكني أقوم بالفعل بإعداد ملف FailureText خاصية إلى الخطأ الوصفي الذي تم إرجاعه من الاستجابة في المكالمة الأولى ، والتي كانت هدفي. لم أكن مانع من مكالمتين في حالتي. قد تكون قضيتك مختلفة.

أمل أن هذا يساعد شخصاما!

نصائح أخرى

يمكنك القيام بذلك بدلاً من ذلك ، وبهذه الطريقة لا تستدعي طريقة ChangePassword مرتين.

if(response != "success") 
      { 
       e.Cancel = true;
((Literal)changePwdCtrl.ChangePasswordTemplateContainer.FindControl("FailureText")).Text = response;
      }

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

protected void ChangePassword1_ChangingPassword(object sender, LoginCancelEventArgs e)
    {
        try
        {
            ChangePassword c = (ChangePassword)sender;

            MembershipUser mu = Membership.GetUser(c.UserName);

            bool response;

            try
            {
                response = mu.ChangePassword(c.CurrentPassword, c.NewPassword);
            }
            catch (Exception ex)
            {

                response = false;
                e.Cancel = true;
                //ChangePassword1.ChangePasswordFailureText = ex.Message;
                //ChangePassword1_ChangePasswordError(sender, e);      
                //((Literal)ChangePassword1.ChangePasswordTemplateContainer.FindControl("FailureText")).Visible = true;
                ((Literal)ChangePassword1.ChangePasswordTemplateContainer.FindControl("FailureText")).Text = ex.Message;

            }

            if (response)
            {        
                //cancel call to the default membership provider method that will attempt to 
                //change the password again. Instead, replicate the 'steps' of AttemptChangePassword(),  
                //an internal method of the ChangePassword control. 
                //Performing all the steps instead of calling the method because just calling method 
                //does not work for some reason 

                e.Cancel = true;
                FormsAuthentication.SetAuthCookie(c.UserName, false);
                ChangePassword1_ChangedPassword(sender, e);
                MethodInfo successMethodInfo = ChangePassword1.GetType().GetMethod("PerformSuccessAction", BindingFlags.NonPublic | BindingFlags.Instance);
                successMethodInfo.Invoke(ChangePassword1, new object[] { "", "", ChangePassword1.NewPassword });

            }
        }
        catch (Exception ex)
        {            
            throw;
        } 

في وقت من الأوقات ، كنت بحاجة إلى تمرير معلومات من مزود وانتهى بي الأمر فقط في وضع ملف تعريف ارتباط قبل إرجاع منطقك ليتم التقاطه على الطرف الآخر من المكالمة. عملت بشكل جيد.

أعتقد أن الحلول المنظف هو طريقة تغيير WALDPASSWORD لإلقاء استثناء. الاستثناء يحتوي على رسالة الخطأ!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top