reede, 23. august 2013

Reavahetuse näitamine SQL SERVER andmeväljast asp:Label-is

Veebivormi kaudu tekstiboksi sisse reavahetusi sisestades võib tekkida soov pärast need reavahetused säilitada veebis taaskuvamisel

MS SQL SERVER säilitab andmeväljas reavahetusi kui CHAR(10) sümbolit (\n). Andmebaasi väljast saab reavahetust leida PATINDEX('%'+CHAR(10)+'%', ...) funktsiooni abil

SELECT [message_text]
      ,PATINDEX('%'+CHAR(10)+'%',message_text) AS esimene_reavahetus
  FROM [dbo].[MESSAGES]


Kui nüüd vaja reavahetust ka HTML koodina näidata või teha seda nii, et asendad andmebaasi CHAR(10) väärtuse HTML reavahe märgendiga <br />

näiteks kasutab asp:Label mille paneb veel asp:Panel sisse kerimisribade pärast

<asp:Panel runat="server" ID="PanelSisu" Height="250px" ScrollBars="Vertical">
              <asp:Label ID="tbMessageBody" runat="server" ReadOnly="True"></asp:Label>
</asp:Panel> 
Miskipärast aga iga kord SQL SERVER-i CHAR(10) ja C# \n omavahel hästi ei ühildu.

Reeglina peaks töötama järgmine konstruktsioon

string msd = table.Rows[0]["message_text"].ToString();
msd = msd.Replace(Environment.NewLine, "<br />");

aga IIS6 miskipärast ei tööta. Üks mitte eriti ilus lahendus on see, et proovib erinevad variandid läbi. Sobib siis kui regulaaravaldsed pole just tugevaim külg.


string msd = table.Rows[0]["message_text"].ToString();
Regex regex = new Regex(@"(\r\n|\r|\n|\n\r)+"); //IIS6 peale ei tööta, IIS8 töötab
msd = regex.Replace(msd, "<br />");
msd = msd.Replace(Environment.NewLine, "<br />"); //see newline mõnikord ei tööta hästi IIS6
msd = Regex.Replace(msd, @"\r\n?|\n", "<br />");  //IIS6 peale töötab

Viisakas on muidugi väljund ennem AntiXSS teegi funktsioonist GetSafeHtmlFragment läbi lasta.
GetSafeHtmlFragment aga sööb reavahe <br /> märgendi ära.

Üle nurga lahendus võib olla selline, et pöörab reavahe mingiks vähetõenäolise stringijadaks. Näiteks  "#####" ja peale GetSafeHtmlFragment funktsiooni asendab "#####" "<br />" märgendiga


string msd = table.Rows[0]["message_text"].ToString();
Regex regex = new Regex(@"(\r\n|\r|\n|\n\r)+");
msd = regex.Replace(msd, "#####");
msd = msd.Replace(Environment.NewLine, "#####"); //see newline mõnikord ei tööta hästi IIS6
msd = Regex.Replace(msd, @"\r\n?|\n", "#####");  //IIS6 peale töötab
this.tbMessageBody.Text = Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(msd).Replace("#####", "<br />");