2009-07-05 11 views
10

मेरे मास्टरपेज में एक लॉगिन बॉक्स है। जब भी लॉगिन जानकारी सही नहीं होती है, तो मैं उपयोगकर्ता को त्रुटि संदेश दिखाने के लिए ViewData["loginError"] का मूल्यांकन करता हूं।एएसपी.नेट एमवीसी: रिटर्न रीडायरेक्ट और व्यूडाटा

लॉगिन उपयोगकर्ता नियंत्रक की एक क्रिया है, इसलिए लॉग इन वाले फॉर्म में action = "/User/Login" है।

एक उपयोगकर्ता किसी भी पेज से लॉग इन करने का प्रयास कर सकता है, सफलता के मामले में मैं उसे अपने व्यक्तिगत पृष्ठ पर रीडायरेक्ट करता हूं, लेकिन त्रुटि के मामले में मैं चाहता हूं कि वह उसी पृष्ठ पर रहें जहां उसने लॉगिन करने का प्रयास किया था। मैं पाया है कि इस काम करता है:

return Redirect(Request.UrlReferrer.ToString()); 

लेकिन ऐसा लगता है कि, जैसा कि मैंने एक उचित दृश्य वापस नहीं कर रहा हूँ, ViewData पर डेटा खो दिया है, तो मैं त्रुटि संदेश नहीं दिखा सकते हैं।

इस और इसी तरह की समस्याओं को हल करने के तरीके पर कोई सुझाव?

धन्यवाद

उत्तर

14

शायद आप TempData संपत्ति का उपयोग करना चाहते हैं, यह अगले HTTP अनुरोध पर जारी रहेगा।

+1

+1 बस मैं क्या सोच रहा था। MvcContrib में आसान कार्रवाई फ़िल्टर का एक सेट भी है जो मॉडलस्टेट को टेम्पपेस्टेट से और उसके लिए प्रतिलिपि बनाता है ताकि आपके पास रीडायरेक्ट के बाद सत्यापन जानकारी उपलब्ध हो। उदाहरण के लिए इस आलेख में आइटम 13 देखें http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx –

+4

याद रखें TempData सत्र का उपयोग करता है हालांकि राज्य - सभी प्रभावों के साथ। – UpTheCreek

2

नहीं क्यों AJAX के माध्यम से लॉगिन बजाय एक पूरा पोस्ट संभाल? आप JSON के माध्यम से आसानी से स्थिति, एक रीडायरेक्ट यूआरएल, और किसी भी त्रुटि संदेश की आपूर्ति कर सकते हैं।

public ActionResult Logon(string username, string password) 
{ 
    ... 

    // Handle master page login 
    if (Request.IsAjaxRequest()) 
    { 
      if (success) 
      { 
       return Json(new { Status = true, Url = Url.Action("Index", "Home") }); 
      } 
      else 
      { 
       return Json(new { Status = false, Message = ... }); 
      } 
    } 
    else // handle login page logon or no javascript 
    { 
      if (success) 
      { 
       return RedirectToAction("Index", "Home"); 
      } 
      else 
      { 
       ViewData["error"] = ... 
       return View("Logon"); 
      } 
     } 
    } 

क्लाइंट-साइड

$(function() { 
     $('#loginForm input[type=submit]').click(function() { 
      $('#loginError').html(''); 
      $.ajax({ 
      url: '<%= Url.Action("Logon","Account") %>', 
      dataType: 'json', 
      type: 'post', 
      data: function() { return $('#loginForm').serialize(); }, 
      success: function(data,status) { 
       if (data.Status) { 
        location.href = data.Url; 
       } 
       else { 
        $('#loginError').html(data.Message); 
       } 
      } 
      }); 
      return false; 
     }); 
    }); 
+1

हाय, मुझे पता है कि मैं इसे AJAX के माध्यम से संभाल सकता हूं और यही वह है जो मैं करने जा रहा हूं, लेकिन मैं जानना चाहता हूं कि समस्या को हल करने के तरीके के रूप में एक साधारण पोस्ट का उपयोग करते समय कितना समय हो सकता है उपयुक्त, या यहां तक ​​कि बस एक ग्राहक द्वारा आवश्यक है। – pistacchio

+0

आपके पास ऐसा दृश्य हो सकता है जिसे सबमिट किए गए फॉर्म के छिपे पैरामीटर के रूप में त्रुटि सेट पर प्रस्तुत किया जाना चाहिए। दुर्भाग्यवश, आपको लॉगऑन अनुरोध के साथ पास करने के लिए उस दृश्य में निहित किसी भी मॉडल डेटा को क्रमबद्ध करने की भी आवश्यकता होगी क्योंकि अन्यथा अनुरोधों के बीच इसे जारी रखने का कोई तरीका नहीं है। AJAX के साथ ऐसा करना बहुत साफ है। ध्यान दें कि उपरोक्त कोड लॉगऑन पेज पर रीडायरेक्ट करेगा (मूल दृश्य नहीं, हालांकि) यदि जावास्क्रिप्ट उपलब्ध नहीं है। इस तरह मैं इसे संभाल दूंगा - त्रुटि को लॉगऑन पेज में छोड़ दें और उपयोगकर्ता को वहां से पुनः प्रमाणित करने दें। – tvanfosson

1

आम तौर पर सबसे वेब साइटों के लिए, जब उपयोगकर्ता को प्रमाणित करने (पासवर्ड के कारण या तो) असफल, यह एक दूसरे पेज (पासवर्ड की तरह साथ उपयोगकर्ता मदद करने के लिए जाना होगा पुनर्प्राप्त करें, या उपयोगकर्ता को साइन अप करने के लिए कहें) जो एक ही पृष्ठ में रहने के लिए दुर्लभ है। मुझे लगता है कि आप फिर से विचार कर सकते हैं कि आपको वास्तव में उस नेविगेशन की आवश्यकता है जिसका आप उपयोग कर रहे हैं।

ठीक है, अगर आप वास्तव में अपने मॉडल से चिपकना चाहते हैं तो एक समाधान यह है कि आप लॉगिन त्रुटि को यूआरएल में संलग्न कर सकते हैं। उदाहरण के लिए, http://www.example.com/index.aspx?login_error=1 इंगित करता है कि त्रुटि तब होती है, और आप BEGIN_REQUEST (या HTTP मॉड्यूल) का उपयोग इस पर कब्जा करने के कर सकते हैं और त्रुटि के बारे में मॉडल राज्य बताओ: Btw

ModelState.AddModelError(...); 

, जोड़ने मॉडल त्रुटि वास्तव में एक और अधिक उचित तरीका है व्यूस्टेट का उपयोग करने के बजाए किसी भी त्रुटि के बारे में दृश्य को सूचित करने के लिए (यह अपवाद फेंकने के समान है और पुराने दिनों में निष्पादन परिणाम के बारे में एक पूर्णांक लौटा रहा है)।

लॉगिन करने के लिए AJAX का उपयोग करते समय (tvanfosson द्वारा सुझाए गए अनुसार) पूरी तरह से प्राप्त करने योग्य है और कभी-कभी उपयोगकर्ता अनुभव में उत्कृष्टता प्राप्त होती है, क्लासिक पूर्ण-पोस्ट अभी भी अपरिवर्तनीय है (मान लें कि कुछ उपयोगकर्ता जावास्क्रिप्ट को अक्षम कर देंगे, या यहां तक ​​कि मेरे डंप WM6 हैंडसेट पर भी जावास्क्रिप्ट का समर्थन नहीं करते हैं)।

+0

जबकि मेरा कोड नमूना पूरा नहीं हुआ है, मुझे लगता है कि इसकी संरचना उस मामले को संभालेगी जहां जावास्क्रिप्ट उपलब्ध नहीं है। उस स्थिति में लॉगऑन फॉर्म एक पूर्ण पोस्ट करेगा और आपके द्वारा वर्णित लॉगऑन पेज पर किसी भी त्रुटि को रीडायरेक्ट किया जाएगा। – tvanfosson

+0

यदि कोई जेएस नहीं है, और मेरी परियोजनाओं के लिए मैं दोनों का उपयोग भी करता हूं तो AJAX + फॉर्म पोस्ट दोनों का उपयोग करने पर सहमत हूं। लेकिन पिस्ताकियो की समस्या अभी भी बनी हुई है। – xandy

1

मैं उलझन में हूं।

return View(); 

बस वर्तमान पृष्ठ को वापस लौटाएं?

तो आपके मामले में, जब लॉगिन विफल रहता है, तो अपना व्यूडाटा सेट करें और वापसी वापसी देखें();

अर्थात

if (!FailedLogin) { 
    //Go to success page 
}else{ 
    //Add error to View Data or use ModelState to add error 
    return View(); 
} 

आप [अधिकृत] डेकोरेटर का उपयोग कर रहे हैं? एमवीसी लॉगिन प्रक्रिया ऑटो लॉगिन पृष्ठ के साथ संकेत देता है और फिर आपको उस नियंत्रक क्रिया पर लौटाता है जिसे आप निष्पादित करने का प्रयास कर रहे थे। बहुत सारे पुनर्निर्देशन पर बंद हो जाता है।

+2

देखें() कार्रवाई के लिए डिफ़ॉल्ट दृश्य देता है, जो वर्तमान दृश्य हो सकता है या नहीं भी हो सकता है। यदि आप मॉडल के साथ विचारों का उपयोग कर रहे हैं, तो इसमें मौजूदा दृश्य, या किसी भी अन्य पैरामीटर द्वारा उपयोग किए जाने वाले मॉडल को शामिल नहीं किया जाएगा। – Suncat2000

1

निम्न उदाहरण उम्मीद है कि आप इस मुद्दे को हल करने में मदद करेंगे:

View.aspx

<%= Html.ValidationSummary("Login was unsuccessful. Please correct the errors and try again.") %> 
<% using (Html.BeginForm()) { %> 
    <div> 
     <fieldset> 
      <legend>Account Information</legend> 
      <p> 
       <label for="username">Username:</label> 
       <%= Html.TextBox("username") %> 
       <%= Html.ValidationMessage("username") %> 
      </p> 
      <p> 
       <label for="password">Password:</label> 
       <%= Html.Password("password") %> 
       <%= Html.ValidationMessage("password") %> 
      </p> 
      <p> 
       <%= Html.CheckBox("rememberMe") %> <label class="inline" for="rememberMe">Remember me?</label> 
      </p> 
      <p> 
       <input type="submit" value="Log On" /> 
      </p> 
     </fieldset> 
    </div> 
<% } %> 

AccountController.cs

private bool ValidateLogOn(string userName, string password) 
{ 
    if (String.IsNullOrEmpty(userName)) 
    { 
     ModelState.AddModelError("username", "You must specify a username."); 
    } 
    if (String.IsNullOrEmpty(password)) 
    { 
     ModelState.AddModelError("password", "You must specify a password."); 
    } 
    if (!MembershipService.ValidateUser(userName, password)) 
    { 
     ModelState.AddModelError("_FORM", "The username or password provided is incorrect."); 
    } 
    return ModelState.IsValid; 
} 

आप नहीं होगा रीडायरेक्ट कार्रवाई के बाद ViewData में जोड़े गए जानकारी को कैप्चर करने में सक्षम। तो सही दृष्टिकोण एक ही दृश्य() को वापस करना है और "xandy" द्वारा उल्लिखित त्रुटियों के लिए मॉडलस्टेट का उपयोग करना है।

आशा है कि यह आपको फॉर्म सत्यापन के साथ एक प्रमुख शुरुआत देगा।

संबंधित मुद्दे