(ASP.NET) ASP.NET (2006 год)

FeedBack-страничка

Я долго колебался, выкладывать ли эту страничку, ибо я не люблю раскрывать всякие критические технологии, связанные с криптографией и прочими подобными фишками, но потом все-таки решился. Ведь этот сайт рассчитан не на дураков, а умные люди и так знают множество способов решения поставленной задачи.

Я расскажу на этой страничке, один из простейших способов организации FeedBack-странички в ASP2:





Для начала, нам потребуется вот такой контрольчик:

00001: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Image.aspx.vb" Inherits="Control_Image" %>
00002: 
00003: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
00004: 
00005: <html xmlns="http://www.w3.org/1999/xhtml" >
00006: <head runat="server">
00007:     <title>Untitled Page</title>
00008: </head>
00009: <body>
00010:     <form id="form1" runat="server">
00011:     <div>
00012:         эта страничка - просто способ записать в поток браузера в формате IMAGE/BMP</div>
00013:     </form>
00014: </body>
00015: </html>
00001: Partial Class Control_Image
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00005:         Dim X As Drawing.Bitmap
00006:         Try
00007:             X = Session("Image")
00008:             Response.ContentType = "image/bmp"
00009:             X.Save(Response.OutputStream, Drawing.Imaging.ImageFormat.Gif)
00010:         Catch ex As Exception
00011:             '
00012:         End Try
00013:     End Sub
00014: End Class

Фактически, это просто вывод графики в поток браузера. Второй контрол тоже несложный - фон на цифры тут наложен простейшим образом.

00001: <%@ Control Language="VB" AutoEventWireup="false" CodeFile="Sender.ascx.vb" Inherits="Control_Sender" %>
00002:    <asp:Label ID="L1" runat="server" Font-Names="sans-serif" Font-Size="X-Small" Text="Для отправки сообщения введите это число: "></asp:Label>
00003:    <asp:Image ID="I1" runat="server" ImageUrl="~/Control/Image.aspx" />
00004:    <asp:Label ID="L2" runat="server" Font-Names="sans-serif" Font-Size="X-Small" Text="и подтвердите ввод: "></asp:Label>
00005:    <asp:TextBox ID="T1" runat="server" MaxLength="4" Width="64px"></asp:TextBox>
00006:    <asp:Button ID="B1" runat="server" Text="Я не робот." />
00007:    <asp:RegularExpressionValidator ID="REV1" runat="server" ControlToValidate="T1"  ErrorMessage="Четыре символа, плиз." 
00008:         Font-Names="sans-serif" Font-Size="X-Small" ValidationExpression="\S\S\S\S"></asp:RegularExpressionValidator>
00001: 'контрол генерации четырех цифр верменного пароля и проверки корректности их ввода
00002: Partial Class Control_Sender
00003:     Inherits System.Web.UI.UserControl
00004: 
00005:     Public Event Send()
00006: 
00007:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00008:         If Not IsPostBack Then
00009:             Call NewPass()
00010:         End If
00011:     End Sub
00012: 
00013:     Protected Sub B1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles B1.Click
00014:         If T1.Text.ToUpper = Session("Password") Then
00015:             RaiseEvent Send()
00016:         Else
00017:             SH.Common.ErrorMessage(Me.Page, "Подбор пароля", T1.Text)
00018:             Call NewPass()
00019:         End If
00020:     End Sub
00021: 
00022:     Private Sub NewPass()
00023:         Dim GU As Guid = Guid.NewGuid
00024:         Dim GS As String = GU.ToString
00025:         Dim G4 As String = GS.Substring(0, 4).ToUpper
00026:         Dim X As New Drawing.Bitmap(60, 20)
00027:         Dim G As Drawing.Graphics = Drawing.Graphics.FromImage(X)
00028:         G.Clear(Drawing.Color.White)
00029:         G.DrawLine(Drawing.Pens.SkyBlue, 0, 0, 60, 20)
00030:         G.DrawLine(Drawing.Pens.Red, 0, 10, 30, 20)
00031:         G.DrawLine(Drawing.Pens.Red, 30, 0, 60, 10)
00032:         G.DrawLine(Drawing.Pens.SkyBlue, 0, 20, 60, 0)
00033:         G.DrawLine(Drawing.Pens.Red, 0, 10, 30, 0)
00034:         G.DrawLine(Drawing.Pens.Red, 30, 20, 60, 10)
00035:         G.DrawString(G4, New Drawing.Font("", 20, Drawing.FontStyle.Italic, Drawing.GraphicsUnit.Pixel), Drawing.Brushes.DarkBlue, 0, -2)
00036:         Session("Image") = X
00037:         Session("Password") = G4
00038:     End Sub
00039: End Class

Ну и наконец, страничка с критической технологией. Обратите внимание на обязательное использование здесь многопоточности.

00001: Partial Class Page5
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub Sender1_Send() Handles Sender1.Send
00005:         SenderStat = Request.Params("ALL_RAW") & vbCrLf & vbCrLf & vbCrLf
00006:         Dim X As New System.Threading.Thread(AddressOf SendMail)
00007:         X.Start()
00008:         Response.Redirect("~/Page51.aspx")
00009:     End Sub
00010: 
00011:     Dim SenderStat As String = ""
00012: 
00013:     Private Sub SendMail()
00014:         Dim Email As New System.Net.Mail.MailMessage("XXXXXXXXX@list.ru", "YYYYYYYYYY@mail.ru", "Soft-help.Ru", SenderStat & T1.Text)
00015:         'Email.IsBodyHtml=True           'для форматированной почты
00016:         'Email.Attachments.Add(New system.Net.Mail.Attachment(...)) 
00017:         Dim MailClient As New System.Net.Mail.SmtpClient()
00018:         Dim basicAuthenticationInfo As New System.Net.NetworkCredential("UUUUUUUUU", "VVVVVVVVVV")
00019:         MailClient.Host = "smtp.list.ru"
00020:         MailClient.UseDefaultCredentials = False
00021:         MailClient.Credentials = basicAuthenticationInfo
00022:         Try
00023:             MailClient.Send(Email)
00024:         Catch ex As Exception
00025:             SH.Common.ErrorMessage("SendMail", ex.Message)
00026:         End Try
00027:     End Sub
00028: End Class

Как видите, все просто и без изысков, но аутентификацию проходим на ура:




Эту идею тоже можно обернуть примерно в такой стандартный библиотечный модуль:

00001: Public Class Mail
00002:     Public Shared Function Send(ByVal myMessage As String) As String
00003:         Return Send(myMessage, "NoReply@sal.ch", "Error auf www.sal.ch", System.Configuration.ConfigurationManager.AppSettings("AdminEmail").ToString, False)
00004:     End Function
00005: 
00006:     Public Shared Function Send(ByVal myMessage As String, ByVal Recipient As String) As String
00007:         Return Send(myMessage, Recipient, "Error auf www.sal.ch", System.Configuration.ConfigurationManager.AppSettings("AdminEmail").ToString, False)
00008:     End Function
00009: 
00010:     Public Shared Function Send(ByVal myMessage As String, ByVal Recipient As String, ByVal Subject As String) As String
00011:         Return Send(myMessage, Recipient, Subject, System.Configuration.ConfigurationManager.AppSettings("AdminEmail").ToString, False)
00012:     End Function
00013: 
00014:     Public Shared Function Send(ByVal myMessage As String, ByVal Recipient As String, ByVal Subject As String, ByVal ByFrom As String) As String
00015:         Return Send(myMessage, Recipient, Subject, ByFrom, False)
00016:     End Function
00017: 
00018:     Public Shared Function Send(ByVal myMessage As String, ByVal Recipient As String, ByVal Subject As String, ByVal ByFrom As String, ByVal TextOnly As Boolean) As String
00019:         Dim EMail As New System.Net.Mail.MailMessage(Recipient, ByFrom)
00020:         If TextOnly Then
00021:             EMail.Body = myMessage
00022:             EMail.IsBodyHtml = False
00023:         Else
00024:             EMail.Body = "<html><head><title></title></head> <body><font face=""Arial"">" & myMessage & " </font></body></html>"
00025:             EMail.IsBodyHtml = True
00026:         End If
00027:         EMail.Subject = Subject
00028:         Dim MailClient As New System.Net.Mail.SmtpClient()
00029:         MailClient.UseDefaultCredentials = False
00030:         Dim basicAuthenticationInfo As New System.Net.NetworkCredential _
00031:         (System.Configuration.ConfigurationManager.AppSettings("SMTP_Login"), _
00032:         System.Configuration.ConfigurationManager.AppSettings("SMTP_Pass"))
00033:         MailClient.Host = System.Configuration.ConfigurationManager.AppSettings("SMTP_Sever")
00034:         MailClient.Credentials = basicAuthenticationInfo
00035:         Try
00036:             MailClient.Send(EMail)
00037:             Return "OK"
00038:         Catch ex As Exception
00039:             'для WEB на HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog требует FULL Control для учетной записи ASP.NET и NETWORK SERVICE
00040:             Dim LogMSG As New System.Text.StringBuilder("Error in MAIL Service <" & MailClient.Host & ">" & vbCrLf & ex.Message & vbCrLf)
00041:             If Not (ex.InnerException Is Nothing) Then
00042:                 LogMSG.AppendLine(ex.InnerException.ToString)
00043:                 LogMSG.AppendLine()
00044:             End If
00045:             If Not (ex.StackTrace Is Nothing) Then
00046:                 LogMSG.AppendLine(ex.StackTrace)
00047:             End If
00048:             LogMSG.AppendLine()
00049:             If Not (MailClient.Host Is Nothing) Then
00050:                 LogMSG.AppendLine("MailClient.Host:" & MailClient.Host & vbCrLf)
00051:             End If
00052:             If Not (MailClient Is Nothing) Then
00053:                 LogMSG.AppendLine("MailClient.Port:" & MailClient.Port & vbCrLf)
00054:             End If
00055:             LogMSG.AppendLine()
00056:             If Not (EMail.From.Address Is Nothing) Then
00057:                 LogMSG.AppendLine("EMail.From.Address:" & EMail.From.Address & vbCrLf)
00058:             End If
00059:             If Not (EMail.To(0).Address Is Nothing) Then
00060:                 LogMSG.AppendLine("EMail.To(0).Address:" & EMail.To(0).Address & vbCrLf)
00061:             End If
00062:             If Not (EMail.Subject Is Nothing) Then
00063:                 LogMSG.AppendLine("EMail.Subject:" & EMail.Subject & vbCrLf)
00064:             End If
00065:             If Not (EMail.Body Is Nothing) Then
00066:                 LogMSG.AppendLine("EMail.Body:" & EMail.Body & vbCrLf)
00067:             End If
00068:             Dim Encoder As New Text.ASCIIEncoding
00069:             If System.Web.HttpContext.Current Is Nothing Then
00070:                 System.Diagnostics.EventLog.WriteEntry("MailService", LogMSG.ToString, Diagnostics.EventLogEntryType.Error, 500, 1)
00071:             Else
00072:                 System.Diagnostics.EventLog.WriteEntry("MailService", LogMSG.ToString, Diagnostics.EventLogEntryType.Error, 500, 1, Encoder.GetBytes(System.Web.HttpContext.Current.Request.Url.PathAndQuery))
00073:             End If
00074:             Throw New Exception("Error in MAIL Service <" & MailClient.Host & ">" & vbCrLf & ex.Message & vbCrLf, ex)
00075:         End Try
00076:     End Function
00077: End Class

В таком случае мы получим чтение всех параметров из конфигурации и полную обработку ошибок. В форме странички с ошибкой, выданной юзеру и записи в журнал. Только обратите внимание на указанные выше необходимые разрешения для доступа к журналу системы.






Кстати то, что на заднем фоне - это самый первый мой Custom-контрол, написанный еще в 2004 году. Это вообще говоря, один из самых несовершенных примеров моего кода, лежащих на этом сайте. Я заранее говорю об этом. Он, вероятно, не потянет работу при МАССОВЫХ ошибках. Но он работает исключительно надежно и удобно в режиме отладки и не раз помогал мне. Я использовал его много раз - например тут при выкладывании сайта на хостинг он сразу же зафиксировал ошибку кошмара DLL, когда на хостинге присутсвовал NET.Framework 2, но сборка Бейсика имела совершенно ИНОЕ имя, чем обычно. Между тем стандартное сообщение в этом случае заключалось в том, что страничка просто отсутствовала. Хотя внешне страничка вполне присутствовала - она не могла ЛИШЬ быть ЗАПУЩЕНА, ибо не могли быть разрешены ССЫЛКИ на библиотеку поддержки бейсика с совершенно иным строгим именем.

Когда я столкнулся впервые с ситуацией кошмара DLL в NET.Framework 2.0 - я чуть с ума не сошел, пытаясь понять, почему же на хостинге сайт не работает. Однако этот контрол дает полный просмотр стека, и в последующих случаях с кошмаром DLL я уже сразу понимал, что дело не в остсутcтвии странички как таковой, и именно в невозможности ее запуска по причине ИНОГО строгого имени у того же самого компонента NET.FRAMEWORK в другой виндузне.


Для использования этот контрол обычно размещается на страничке обработки ошибок - ведь он еще и выводит все Сессион, чем гораздо удобнее стандартного сообщения об ошибке. Сгрузить этот контрол в готовом виде отсюда. Контрол надо добавить на панель ТулБоксов VS2005 и потом просто перетащить на форму обработки ошибок сайта и, главное, обеспечить его вызов из GLOBAL.ASaX





Далее приводится его текст в полном виде, однако не забудьте, чтоб он все показал, надо еще и указать это в Web-config (естественно при работе сайта в боевом режиме - делать это совсем не обязательно):



00001: Imports System
00002: Imports System.Collections.Generic
00003: Imports System.ComponentModel
00004: Imports System.Text
00005: Imports System.Web
00006: Imports System.Web.UI
00007: Imports System.Web.UI.WebControls
00008: 
00009: 
00010: <DefaultProperty("ErrorMessage")> _
00011: <System.Drawing.ToolboxBitmap(GetType(AspErrorInfo), "i280.ico")> _
00012: Public Class AspErrorInfo
00013:     Inherits WebControl
00014: 
00015:     ''' <summary>
00016:     ''' Этот метод должен быть вызван в Global.ASAX - Application_Error
00017:     ''' </summary>
00018:     Public Shared Sub ErrorRedirections()
00019:         Dim ExceptionS As New System.Collections.Generic.SortedList(Of String, System.Exception())
00020:         ExceptionS.Add(System.Web.HttpContext.Current.Request.Url.PathAndQuery, System.Web.HttpContext.Current.AllErrors)
00021:         Try
00022:             System.Web.HttpContext.Current.Application("ErrorPages") = ExceptionS
00023:             System.Web.HttpContext.Current.Response.Redirect("~/Error1.aspx")
00024:         Catch ex As System.Exception
00025:             System.Web.HttpContext.Current.Response.Write("Error page is missing")
00026:         End Try
00027:         System.Web.HttpContext.Current.Response.End()
00028:     End Sub
00029: 
00030:     Dim _ErrorMessage As String
00031:     <Bindable(False), Category("Misc"), DefaultValue("При выполнении вашего запроса возникла следующая ошибка:"), Localizable(True)> _
00032:     Public Property ErrorMessage() As String
00033:         Get
00034:             ErrorMessage = _ErrorMessage
00035:         End Get
00036:         Set(ByVal value As String)
00037:             _ErrorMessage = value
00038:         End Set
00039:     End Property
00040: 
00041:     Dim _ErrorTitleDiv As String
00042:     <Bindable(False), Category("Misc"), DefaultValue("<span style='font-size: normal; color: darkred'>"), Localizable(True)> _
00043:        Public Property ErrorTitleDiv() As String
00044:         Get
00045:             ErrorTitleDiv = _ErrorTitleDiv
00046:         End Get
00047:         Set(ByVal value As String)
00048:             _ErrorTitleDiv = value
00049:         End Set
00050:     End Property
00051: 
00052:     Dim _ErrorMessageDiv As String
00053:     <Bindable(False), Category("Misc"), DefaultValue("<span style='font-size: x-small; color: darkred'>"), Localizable(True)> _
00054:     Public Property ErrorMessageDiv() As String
00055:         Get
00056:             ErrorMessageDiv = _ErrorMessageDiv
00057:         End Get
00058:         Set(ByVal value As String)
00059:             _ErrorMessageDiv = value
00060:         End Set
00061:     End Property
00062: 
00063:     Dim _ErrorPageDiv As String
00064:     <Bindable(False), Category("Misc"), DefaultValue("<span style='font-size: large; color: black'>"), Localizable(True)> _
00065:     Public Property ErrorPageDiv() As String
00066:         Get
00067:             ErrorPageDiv = _ErrorPageDiv
00068:         End Get
00069:         Set(ByVal value As String)
00070:             _ErrorPageDiv = value
00071:         End Set
00072:     End Property
00073: 
00074:     Dim _ErrorCountDiv As String
00075:     <Bindable(False), Category("Misc"), DefaultValue("<span style='font-size: xx-small; color: black'>"), Localizable(True)> _
00076:     Public Property ErrorCountDiv() As String
00077:         Get
00078:             ErrorCountDiv = _ErrorCountDiv
00079:         End Get
00080:         Set(ByVal value As String)
00081:             _ErrorCountDiv = value
00082:         End Set
00083:     End Property
00084: 
00085:     Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter)
00086:         Dim HtmlOut As New System.Text.StringBuilder
00087:         Dim PageName As String 'страничка с ошибкой
00088:         '
00089:         HtmlOut.Append(_ErrorTitleDiv & _ErrorMessage & "</span><br />")
00090:         Dim ExceptionS As New Collections.Generic.SortedList(Of String, System.Exception())
00091:         If System.Web.HttpContext.Current.Application("ErrorPages") IsNot Nothing Then
00092:             ExceptionS = System.Web.HttpContext.Current.Application("ErrorPages")
00093:             If ExceptionS.Count >= 1 Then
00094:                 PageName = ExceptionS.Keys(0)
00095:                 HtmlOut.Append(_ErrorPageDiv & PageName.ToString & "</span><br>")
00096:                 HtmlOut.Append(_ErrorCountDiv )
00097:                 'в месте до слеша выводится общий список необработанных ошибок приложения в данный момент времени (в запросах всех юзеров)
00098:                 If ExceptionS.Count > 1 Then HtmlOut.Append("(" & ExceptionS.Count.ToString)
00099:                 '
00100:                 If System.Configuration.ConfigurationManager.AppSettings("FullErrorMesssage") IsNot Nothing Then
00101:                     If System.Configuration.ConfigurationManager.AppSettings("FullErrorMesssage") Then
00102:                         If ExceptionS.Item(PageName) IsNot Nothing Then
00103:                             'выводится только ОДНА из общего списка ошибок, возникших от выполнения запроса
00104:                             'однако в метке после слеша выводится общее количество ошибок запроса
00105:                             If ExceptionS.Count > 1 Then
00106:                                 HtmlOut.Append(" / " & ExceptionS.Item(PageName).Length & " ) </span")
00107:                             Else
00108:                                 HtmlOut.Append("</span>")
00109:                             End If
00110:                             HtmlOut.Append(_ErrorMessageDiv)
00111:                             HtmlOut.Append(ExceptionS.Item(PageName)(0).Message)
00112:                             If Not (ExceptionS.Item(PageName)(0).Source Is Nothing) Then
00113:                                 HtmlOut.AppendLine()
00114:                                 HtmlOut.AppendLine(ExceptionS.Item(PageName)(0).Source)
00115:                             End If
00116:                             If Not (ExceptionS.Item(PageName)(0).InnerException Is Nothing) Then
00117:                                 HtmlOut.AppendLine()
00118:                                 HtmlOut.AppendLine(ExceptionS.Item(PageName)(0).InnerException.ToString)
00119:                             End If
00120:                             If Not (ExceptionS.Item(PageName)(0).StackTrace Is Nothing) Then
00121:                                 HtmlOut.AppendLine()
00122:                                 HtmlOut.AppendLine(ExceptionS.Item(PageName)(0).StackTrace)
00123:                             End If
00124:                             HtmlOut.Replace(vbCrLf, "<br />")
00125:                             HtmlOut.Append("</span>")
00126:                         End If
00127:                         'далее выведем все сесиионные переменные при возникновении ошибки
00128:                         If System.Web.HttpContext.Current.Session.Count > 0 Then
00129:                             HtmlOut.Append("<table border=1>")
00130:                             For Each Key As String In System.Web.HttpContext.Current.Session.Keys
00131:                                 If System.Web.HttpContext.Current.Session.Item(Key) Is Nothing Then
00132:                                     HtmlOut.Append("<tr><td>" & Key & "</td><td>Nothing</td></tr>")
00133:                                 Else
00134:                                     HtmlOut.Append("<tr><td>" & Key & "</td><td>" & System.Web.HttpContext.Current.Session.Item(Key).ToString & "</td></tr>")
00135:                                 End If
00136:                             Next
00137:                             HtmlOut.Append("</table>")
00138:                         End If
00139:                     Else
00140:                         If ExceptionS.Item(PageName) IsNot Nothing Then HtmlOut.Append(_ErrorMessageDiv & System.Web.HttpContext.Current.Server.HtmlEncode(ExceptionS.Item(PageName)(0).Message).ToString & "</span>")
00141:                     End If
00142:                 Else
00143:                     If ExceptionS.Item(PageName) IsNot Nothing Then HtmlOut.Append(_ErrorMessageDiv & System.Web.HttpContext.Current.Server.HtmlEncode(ExceptionS.Item(PageName)(0).Message).ToString & "</span>")
00144:                 End If
00145:                 'выведенное сообщение об ошибке удалили из списка ошибок приложения
00146:                 ExceptionS.Remove(PageName)
00147:                 System.Web.HttpContext.Current.Application("ErrorPages") = ExceptionS
00148:                 output.Write(HtmlOut.ToString)
00149:             End If
00150:         End If
00151: 
00152:     End Sub
00153: End Class

Параметры контролу можно задать так:

00001:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00002:         AspErrorInfo1.ErrorCountDiv = "<span style='font-size: xx-small; color: black'>"
00003:         AspErrorInfo1.ErrorMessage = "При выполнении вашего запроса возникла ошибка:"
00004:         AspErrorInfo1.ErrorMessageDiv = "<span style='font-size: x-small; color: darkred'>"
00005:         AspErrorInfo1.ErrorPageDiv = "<span style='font-size: large; color: black'>"
00006:         AspErrorInfo1.ErrorTitleDiv = "<span style='font-size: normal; color: darkred'>"
00007:     End Sub


Comments ( )
Link to this page: //www.vb-net.com/asp2/8/index.htm
< THANKS ME>