2010-01-30 6 views
9

Ho una casella di testo asp.net come questo:ASP: TextBox Valore scompare nel postback solo quando la password

<asp:TextBox ID="PINPad" runat="server" Columns="6" MaxLength="4" 
     CssClass="PINTextClass"></asp:TextBox> 

Si tratta, come si può immaginare, la casella di testo da un PIN pad su schermo. Javascript inserisce i valori. La pagina viene registrata ogni cinque secondi (utilizzando un pannello di aggiornamento se questo è importante) per aggiornare vari altri elementi non correlati sullo schermo. Questo funziona bene.

Tuttavia, quando ho convertirla in una casella di testo della password, in questo modo:

<asp:TextBox ID="PINPad" runat="server" Columns="6" MaxLength="4" 
     CssClass="PINTextClass" TextMode="Password"></asp:TextBox> 

Poi ogni volta che i posti pagina indietro, la casella di testo viene azzerato fuori sullo schermo e la casella di testo è vuota (anche se durante l'evento del timer, il valore lo fa ritornare al server.)

Qualche suggerimento su come risolvere questo problema, in modo che mantenga il suo valore durante il postback?

+3

C'è articolo su come risolvere questo in modo più sicuro (se non perfettamente) a http://www.codeproject.com/Articles/18927/How-to-safely-keep-a-password- campo durante-postbac – Mark

risposta

15

Come funzionalità di sicurezza, ASP.NET tenta di non consentire all'utente di inviare nuovamente il valore della password al client. Se stai bene con i problemi di sicurezza (ovvero non sono informazioni veramente sicure o sei sicuro che la connessione sia sicura), puoi impostare manualmente l'attributo "value" del controllo, piuttosto che usare la sua proprietà Text. Potrebbe sembrare qualcosa di simile:

this.PINPad.Attributes.Add("value", this.PINPad.Text); 
0

qui è un altro modo per farlo: -

using System; 
using System.Text; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace WebControlLibrary 
{ 
    public class PWDTextBox : TextBox 
    { 
     public PWDTextBox() 
     { 
      this.TextMode = TextBoxMode.Password; 
     } 

     public string Password 
     { 
      get 
      { 
       string val = (string)ViewState["pwd"]; 
       if (string.IsNullOrEmpty(val)) 
       { 
        return ""; 
       } 
       else 
       { 
        return val; 
       } 
      } 
      set 
      { 
       ViewState["pwd"] = value; 
      } 
     } 

     public override string Text 
     { 
      get 
      { 
       return Password; 
      } 
      set 
      { 
       Password = value; 
      } 
     } 

     protected override void OnPreRender(EventArgs e) 
     { 
      base.OnPreRender(e); 
      this.Text = Password; 
     } 

     protected override void AddAttributesToRender(HtmlTextWriter writer) 
     { 
      base.AddAttributesToRender(writer); 
      writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Password); 
     } 
    } 
} 
0

Il problema di perdere la password nel postback può essere evitare di fare uso di Asynchronous JavaScript chiama, consente descrivere uno scenario tipico di una pagina di login:

consente di dire che abbiamo una pagina di login, che permette all'utente di cambiare la lingua delle sue etichette quando l'utente sceglie una lingua con una DropDownList

enter image description here

una soluzione potrebbe essere quella di richiamare SelectedIndexChanged caso di DropDownList, fare un postback che va al server e raccoglie le etichette nella lingua scelta.

in questo scenario la password del campo andrà persa a causa della funzionalità di sicurezza di ASP.NET che rende i campi delle password non persistenti tra i postback.

Questo scenario può essere risolto se il postback viene evitato utilizzando le chiamate Asynchronous Technology e XML (Ajax).

aggiungere una funzione javascript che verrà richiamato dal controllo DropDownList, in questo caso, questa funzione viene assegnata alla proprietà Comando della dropdownlist in codice dietro:

function ValueChanged(div) 
      { 
       var table = div.getElementsByTagName("table"); 
       if (table && table.length > 0) 
       { 
        var t = table[0].getAttribute('type'); 
        if (t != null && (t == "DropDown")) 
        { 
         var inputs = div.getElementsByTagName("input"); 
         if (inputs && inputs.length == 2) 
         { 

          { 
           Translate(inputs[1].value); 
          } 
         } 
        } 
       } 
      } 

La Tradurre funzione prende come parametro selezionato opzione lingua nel controllo a discesa ed esegue la chiamata asincrona come mostrato di seguito.

function Translate(lang) 
      { 
       var request = null; 
       if (window.XMLHttpRequest) 
       { 
        request = new XMLHttpRequest(); 
        if (request.overrideMimeType) 
        {       
         request.overrideMimeType('text/xml'); 
        } 
       } 
       else if (window.ActiveXObject) 
       { 
        request = new ActiveXObject("Msxml2.XMLHTTP"); 
       } 
       if (request == null) 
       { 
        return; 
       } 
       var url = "GetLoginTranslations.aspx";    
       request.open('GET', url +'?lang=' + lang, true); 
       request.setRequestHeader("Cache-Control", "no-cache"); 
       request.setRequestHeader("Pragma", "no-cache"); 
       request.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); 
       request.onreadystatechange = function() { TranslateLabels(request); }; 
       request.send(null); 
      } 

La funzione translate mostrato sopra esegue la chiamata e ottenere i risultati nella pagina aspx specificato (in questo caso "GetLoginTranslations.aspx ")

quando la richiesta è completata e l'request.onreadystatechange viene impostato sui TranslateLabels funzione viene eseguita questa funzione.

in questo modo il postback non viene eseguito come prima in caso OnSelectedIndexChanged del dropdownlist . controllo

la funzione TranslateLabels sarebbe qualcosa di simile:

function TranslateLabels(request) 
      {     
       if (request.readyState == 4) 
       { 
        if (request.status == 200) 
        { 
         if (request.responseXML) 
         { 
          var objRoot = request.responseXML.documentElement; 
          if (objRoot) 
          { 
           if (objRoot.nodeName == "strings") 
           { 
            for (var i = 0; i < objRoot.childNodes.length; i++) 
            { 
             var node = objRoot.childNodes[i]; 
             var elem; 
             switch (node.getAttribute("id")) 
             { 
              case "lbl_login": 
               elem = document.getElementById("lbl_login"); 
               if (elem) 
                elem.innerHTML = node.firstChild.nodeValue; 
               break; 
             } 
///.... 
} 
} 
} 
} 
} 
} 

il request.responseXML contiene il codice XML incorporato nella pagina GetLoginTranslations.aspx e la struttura di questo XML è definito lì.

il Page Load() evento nel GetLoginTranslations.aspx dovrebbe essere simile:

protected void Page_Load(object sender, EventArgs e) 
     { 
    if (Request["lang"] != null) 
       strLang = Request["lang"]; 

      //init response 
      Response.Clear(); 
      Response.Cache.SetExpires(DateTime.Now); 
      Response.Cache.SetCacheability(HttpCacheability.NoCache); 
      Response.Cache.SetValidUntilExpires(true); 
      Response.ContentType = "application/xml"; 
      Response.Charset = "utf-8"; 


      XmlTextWriter xml = new XmlTextWriter(Response.OutputStream, System.Text.Encoding.UTF8) 
      { 
       Formatting = Formatting.None 
      }; 
      xml.WriteStartDocument(); 
      xml.WriteStartElement("strings"); 

      xml.WriteStartElement("string"); 
      xml.WriteAttributeString("id", "lbl_login"); 
      xml.WriteString(GetTranslation("label_login", strLang)); 
      xml.WriteEndElement(); 

      // ... the other labels 


      xml.WriteEndElement(); //</strings> 
      xml.Close(); 

     } 

Alcune altre considerazioni:

  • impostare la proprietà AutoPostBack del dropdownlist su false.
3
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack) 
    { 
     if (!(String.IsNullOrEmpty(txtPwd.Text.Trim()))) 
     { 
      txtPwd.Attributes["value"]= txtPwd.Text;    
     } 
     if (!(String.IsNullOrEmpty(txtConfirmPwd.Text.Trim()))) 
     { 
      txtConfirmPwd.Attributes["value"] = txtConfirmPwd.Text; 
     } 
    } 
}