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

Этюды на ASP2. Простейший баг-трекер.

Микрософт предполагает, что для учета багов в программе народ будет применять TEAM FOUNDATION SERVER. Что ж, это не исключено, если у вас есть заведомо лишние семь тысяч долларов. А можете установить вот эту мою прогу, которую я публикую здесь с открытым исходным кодом.


К моей проге тут еще не прикручет репорт-сервер и вот таких симпотичных отчетов, как в TFS - вы в ней не получите пока не докрутите сюда reportviewer, но во многих отношениях даже такой элементарный багтрекер гораздо более практичен и функционален, чем навороченный микрософтовский монстр.

Ну хотя бы в той части, что тупой мискрософтовский монстр не позволяет ВЕСТИ ОБСУЖДЕНИЕ проблемы. Сценарий предполагает что тестер вбил ошибку, а программер ее исправил. И все. Да, в теории все красиво. Но в жизни - тестеры, это малоквалифицированные полуставочники и половина того, что они вбивают как баги - является совершенно безумным бредом. И требует тчательного разжевавания программистом азбуки ASP.NET или, например, различий между обязанностями программиста и обязанностями верстальщика. Во многих случаях так называемые баги не имеют даже косвенного отношения к программисту - например модератор ведет в SQL базу стран - а тестеры вбивают программеру баг: "почему у вас сайт показывает страну Умумбу - такой страны нету!".


Собственно говоря, на моем сайте лежит МНОЖЕСТВО описаний различных моих баг-трекеров, сделанных мною в разные годы для разных фирм. Например тут - лежит мой баг-трекер для WIN-приложений 2005-го года рождения, который я сделал для ДигиталШопа.

Кроме того, в 2007-м году я работал в одном шизоидном микрософтовском проекте, практическое приложение которого было тоже в виде баг трекера. Это такой универсальный конфигуратор, который позволял смоделировать организационную структуру сначала - те тестер, программер. Потом обьекты, которыми манипулирует эта оргструктура - проекты, баги, версии. Потом например программер поправляет баг - идут оповещения между обьектами - тестеру, руководителю проекта, если баг последний - выпускающему Менеджеру проекта. Пара скринов этой шизоидной системы у меня лежит здесь.

Эта система была гораздо лучше TFS и даже немного приближалась по качеству к моим старинным разработкам типа ProjectExplorer, не шизоидность ее заключалась в том, что перед ее пользованием администратора системы, преодолевая тонны документации и горы багов - сначала должен был ее СКОНФИГУРИРОВАТЬ. Те занести в нее тесторов, девелоперов, админов и тд. Потом в жутких муках настроить ОПОВЕЩЕНИЯ, которые система отправляла мылом членам этой организационной структуры...

Не знаю, какой админ бы сумел асилить все глубину микрасофтовских задумок и асилить все конфигурирование очередного микрасофтоского монстра, но... шизо-идея ТЗ состояла в том, что это все надо было выложить в виде публичного сервиса, что-то по типу MAIL.RU - админы организаций бы это чудо конфигурили, а тестеры и проггеры этим чудом бы пользовались. При этом MS собирался НЕ ДОПЛАЧИВАТЬ фирмам за пользование этим своим логическим глюком (моего производства), а ВЗИМАТЬ с них деньги.

Я долго хохотал над этой шизо-идеей, над техническим заданием, над прототипом проекта на PHP, который уже был до начала моей работы в проекте -  но от участия в проекте не отказался, тк очень хочелось бы получть с биллагейтса хоть какие-нибудь деньги. Но как я и предполагал, через несколько месяцев у проекта начались финансовые сложности. Морду микрософатавцам конечно не били, за их грязные предложения оплатить право пользования их чудо-сайтом коммунального баг-трекинга, но денег им никто так и не заплатил. Естественно, с моей ЗП уже через несколько месяцев у них начались сложности и они  разрешились естественным образом - я уволился и этот чудо-проект скорее всего исчез в небытие..

Ну вот, собственно, и весь Background-рассказик у этой моей крошечной проги. Я написал ее за один день - сев за камп часов в шесть вечера. Мне даже лень было для такой крошечной проги придумывать осмысленные имена идентификаторов и обравнивать длины полей на формах и в базе, ибо я ее даже не отлаживал - она пошла сразу. С защитой и безопасностью я тут тоже не заморачивался - это ведь все междусобойчик тестеров и девелоперов. С другой стороны, элементарность этой проги доказывает полный тупизм микрасофтовцев, которые вознамерились на такой крошечной проге, написанной за пару часов  - взимать с народа деньги. Продавать право пользования этим сайтом за нехилые деньги, причем с помесячным поступлением платежей ... Хм, ну надо ж до такого додуматся - изловчится и даже с кучки гавна сладенькую пеночку слизнуть... Ай-да, детеныши билла гейтса !!!

Эта прога элементарно расширяема как в плане отсылки мыльных сообщений, так и в плане отчетов. Только мой вам совет - при расширениях постарайтесь избежать микрософтовского тупизма с безумными глючными конфигураторами шаблонов почтовых сообщений. Делайте все просто - состояние бага такого-то изменилось с такого-то на такое-то. И все. Это ровно одна строка кода на форме BugChange. Ну тут будет куча специфики доступа к  почтовику. И вам проще самому дописать мыльный функционал любимым вами способом, чем разбиратся в причинах неработоспособности моего кода.

Если вы сидите на SQL2005 - тыкайтесь в почтовик через DBMAIL - это лучше чем вот так.


Теперь собственно о проге. Она докручивается в любой ASP.NET сайт, в котором работает AU на стандартной микрософтовской базе юзеров. Прога  состоит из пяти страничек, код которых будет приведен ниже в исходном виде и трех табличек, которые вам надо установить в рабочую базу сайта:

00001: SET ANSI_NULLS ON
00002: GO
00003: SET QUOTED_IDENTIFIER ON
00004: GO
00005: CREATE TABLE [dbo].[BugState](
00006:     [i] [int] IDENTITY(1,1) NOT NULL,
00007:     [Image] [nvarchar](1000) NOT NULL,
00008:     [Descr] [nvarchar](4000) NOT NULL,
00009:  CONSTRAINT [PK_BugState] PRIMARY KEY CLUSTERED 
00010: (
00011:     [i] ASC
00012: ) ON [PRIMARY]
00013: ) ON [PRIMARY]
00014: GO
00015: SET ANSI_NULLS ON
00016: GO
00017: SET QUOTED_IDENTIFIER ON
00018: GO
00019: CREATE TABLE [dbo].[BugComment](
00020:     [i] [int] IDENTITY(1,1) NOT NULL,
00021:     [ToBug] [int] NOT NULL,
00022:     [ToUser] [uniqueidentifier] NOT NULL,
00023:     [Date] [datetime] NOT NULL,
00024:     [NewState] [int] NOT NULL,
00025:     [ToImage] [nvarchar](1000) NULL,
00026:     [Comment] [nvarchar](4000) NULL,
00027:  CONSTRAINT [PK_BugForum] PRIMARY KEY CLUSTERED 
00028: (
00029:     [i] ASC
00030: ) ON [PRIMARY]
00031: ) ON [PRIMARY]
00032: GO
00033: SET ANSI_NULLS ON
00034: GO
00035: SET QUOTED_IDENTIFIER ON
00036: GO
00037: CREATE TABLE [dbo].[Bugs](
00038:     [i] [int] IDENTITY(1,1) NOT NULL,
00039:     [ToState] [int] NOT NULL,
00040:     [TXT] [nvarchar](4000) NULL,
00041:     [Page] [nvarchar](1000) NULL,
00042:     [ToImage] [nvarchar](1000) NULL,
00043:     [CrDate] [datetime] NOT NULL,
00044:     [ToUser] [uniqueidentifier] NOT NULL,
00045:  CONSTRAINT [PK_Bugs] PRIMARY KEY CLUSTERED 
00046: (
00047:     [i] ASC
00048: ) ON [PRIMARY]
00049: ) ON [PRIMARY]
00050: GO
00051: ALTER TABLE [dbo].[BugComment]  WITH CHECK ADD  CONSTRAINT [FK_BugForum_Bugs] FOREIGN KEY([ToBug])
00052: REFERENCES [dbo].[Bugs] ([i])
00053: GO
00054: ALTER TABLE [dbo].[BugComment] CHECK CONSTRAINT [FK_BugForum_Bugs]
00055: GO
00056: ALTER TABLE [dbo].[BugComment]  WITH CHECK ADD  CONSTRAINT [FK_BugForum_BugState1] FOREIGN KEY([NewState])
00057: REFERENCES [dbo].[BugState] ([i])
00058: GO
00059: ALTER TABLE [dbo].[BugComment] CHECK CONSTRAINT [FK_BugForum_BugState1]
00060: GO
00061: ALTER TABLE [dbo].[Bugs]  WITH CHECK ADD  CONSTRAINT [FK_Bugs_BugState] FOREIGN KEY([ToState])
00062: REFERENCES [dbo].[BugState] ([i])
00063: GO
00064: ALTER TABLE [dbo].[Bugs] CHECK CONSTRAINT [FK_Bugs_BugState]
00065: GO
00066: INSERT [BugState]([Image],[Descr]) VALUES(N'Add.gif',N'Проблема сформулирована.')
00067: INSERT [BugState]([Image],[Descr]) VALUES(N'Mail.gif',N'Обсуждение и уточнение задачи.')
00068: INSERT [BugState]([Image],[Descr]) VALUES(N'Time.gif',N'Решение задачи отложено на более позднее время.')
00069: INSERT [BugState]([Image],[Descr]) VALUES(N'Close.gif',N'Задача не может быть выполнена.')
00070: INSERT [BugState]([Image],[Descr]) VALUES(N'Write.gif',N'Задача полностью понятна и взята программистом в разработку.')
00071: INSERT [BugState]([Image],[Descr]) VALUES(N'Atten.gif',N'Обработка проблемы программистом завершена!')
00072: INSERT [BugState]([Image],[Descr]) VALUES(N'Quest.gif',N'Решение задачи не найдено, непонятно или не соответствует поставленной задаче.')
00073: INSERT [BugState]([Image],[Descr]) VALUES(N'OK.gif',N'Решение задачи перепроверено, принято и проблема полностью закрыта.')
00074: GO

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

Теперь собственно код первой формы:



00001: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="BugList.aspx.vb" Inherits="BugList" %>
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>Баг-трекер</title>
00008: </head>
00009: <body>
00010:     <form id="form1" runat="server">
00011:     <div>
00012:     <div style="text-align:center; font-size:20px">
00013:             <asp:HyperLink ID="HyperLink1" NavigateUrl="~/Default.aspx" runat="server">На главную</asp:HyperLink>
00014:             </div>
00015:             <div style="height:10px"></div>
00016:             <table><tr><td>
00017:                 <asp:Label ID="Label1" runat="server" Text="Отобрать только:"></asp:Label>
00018:             </td><td>
00019:                 <asp:ImageButton ID="ImageButton2" ImageUrl="~/BugImage/Info.gif" CommandArgument=0 runat="server" Height="50px" Width="50px" ToolTip="Все" />
00020:             </td><td>
00021:              <asp:ImageButton ID="ImageButton3" ImageUrl="~/BugImage/Add.gif" runat="server" CommandArgument=1 Height="50px" Width="50px" ToolTip="Только что добавленные" />
00022:             </td><td>
00023:              <asp:ImageButton ID="ImageButton4" ImageUrl="~/BugImage/Mail.gif"  CommandArgument="2"  runat="server" Height="50px" Width="50px" ToolTip="Находящиеся в обсуждение и уточнении." />
00024:             </td><td>
00025:              <asp:ImageButton ID="ImageButton5" ImageUrl="~/BugImage/Time.gif"  CommandArgument="3" runat="server" Height="50px" Width="50px" ToolTip="Отложенные на неопределенное время." />
00026:             </td><td>
00027:              <asp:ImageButton ID="ImageButton6" ImageUrl="~/BugImage/Close.gif" CommandArgument="4"  runat="server" Height="50px" Width="50px" ToolTip="Позиции, выполнение которых невозможно." />
00028:             </td><td>
00029:              <asp:ImageButton ID="ImageButton7" ImageUrl="~/BugImage/Write.gif" CommandArgument="5"  runat="server" Height="50px" Width="50px" ToolTip="Находящиеся в данный момент в разработке у программиста." />
00030:             </td><td>
00031:              <asp:ImageButton ID="ImageButton8" ImageUrl="~/BugImage/Atten.gif" CommandArgument="6"  runat="server" Height="50px" Width="50px"  ToolTip="Позиции, разработка которых программистом завершена." />
00032:             </td><td>
00033:               <asp:ImageButton ID="ImageButton9" ImageUrl="~/BugImage/Quest.gif"  CommandArgument="7"  runat="server" Height="50px" Width="50px" ToolTip="Позиции, завершенные  программистом, но не принятые." />
00034:             </td><td>
00035:               <asp:ImageButton ID="ImageButton10" ImageUrl="~/BugImage/OK.gif" CommandArgument="8"  runat="server" Height="50px" Width="50px" ToolTip="Полностью принятые и закрытые позиции." />
00036:             </td>            </tr></table>
00037:         <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
00038:             DataKeyNames="i"  Width="100%" 
00039:             AllowPaging="True" PageSize="20">
00040:             <Columns>
00041:                 <asp:BoundField DataField="i" HeaderText="#" InsertVisible="False" 
00042:                     ReadOnly="True" SortExpression="i" />
00043:              <asp:TemplateField HeaderText="State">
00044:                 <ItemTemplate>
00045:                     <asp:ImageButton ID="ImageButton1" Width="50" Height="50" runat="server" 
00046:                         onclick="ImageButton1_Click" />
00047:                 </ItemTemplate>
00048:             </asp:TemplateField>
00049:             <asp:TemplateField >
00050:                 <ItemTemplate>
00051:                     <asp:Label ID="KTO" runat="server"></asp:Label>
00052:                 </ItemTemplate>
00053:             </asp:TemplateField>
00054:             <asp:TemplateField HeaderText="Bug/Task">
00055:                 <ItemTemplate>
00056:                     <asp:HyperLink ID="HyperLink1" runat="server"  ></asp:HyperLink>
00057:                 </ItemTemplate>
00058:             </asp:TemplateField>
00059:             </Columns>
00060:         </asp:GridView>
00061:     <div style="height:10px"></div>
00062:         <table><tr><td>
00063:     <asp:ImageButton ID="ImageButton1" ImageUrl="~/BugImage/Add.gif" runat="server" 
00064:             Height="50px" Width="50px"  />
00065:     </td><td>
00066:     Добавить новый баг или новую задачу.</td>
00067:     </tr></table>
00068:     </div>
00069:         <asp:SqlDataSource ID="GetBugList" runat="server" 
00070:             ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00071:             SelectCommand="select Bugs.*,Image,Descr  from Bugs join BugState on Bugs.ToState=BugState.i">
00072:         </asp:SqlDataSource>
00073:         <asp:SqlDataSource ID="GetBugList1" runat="server" 
00074:             ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00075:             SelectCommand="select Bugs.*,Image,Descr  from Bugs join BugState on Bugs.ToState=BugState.i where Bugs.ToState=@i">
00076:             <SelectParameters>
00077:                 <asp:Parameter Name="i" />
00078:             </SelectParameters>
00079:         </asp:SqlDataSource>
00080:     </form>
00081: </body>
00082: </html>

00001: Partial Class BugList
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub BugAdd_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00005:         If Not IsPostBack Then
00006:             If User.Identity.Name = "" Then Response.Redirect("~/Default.aspx")
00007:             Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00008:             ImageButton1.PostBackUrl = "~/BugAdd.aspx?i=" & CurUser.ProviderUserKey.ToString
00009:             GridView1.DataSourceID = "GetBugList"
00010:             GridView1.DataBind()
00011:         End If
00012:     End Sub
00013: 
00014:     Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
00015:         If e.Row.DataItem IsNot Nothing Then
00016:             Dim KTO As Label = CType(e.Row.FindControl("KTO"), Label)
00017:             Dim User1 As MembershipUser = Membership.GetUser(e.Row.DataItem("ToUser"))
00018:             KTO.Text = User1.UserName & " (" & e.Row.DataItem("CrDate") & ")"
00019:             Dim ImageButton1 As ImageButton = CType(e.Row.FindControl("ImageButton1"), ImageButton)
00020:             ImageButton1.ToolTip = e.Row.DataItem("Descr")
00021:             ImageButton1.ImageUrl = "~/BugImage/" & e.Row.DataItem("Image")
00022:             ImageButton1.CommandArgument = e.Row.DataItem("i")
00023:             Dim HyperLink1 As HyperLink = CType(e.Row.FindControl("HyperLink1"), HyperLink)
00024:             HyperLink1.NavigateUrl = "~/BugComments.aspx?i=" & User1.ProviderUserKey.ToString & "&j=" & e.Row.DataItem("i")
00025:             HyperLink1.Text = Left(e.Row.DataItem("TXT"), 180) & " ..."
00026:         End If
00027:     End Sub
00028: 
00029:     Protected Sub ImageButton1_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs)
00030:         Dim User1 As MembershipUser = Membership.GetUser(User.Identity.Name)
00031:         Dim ImageButton1 As ImageButton = CType(sender, ImageButton)
00032:         Response.Redirect("~/BugComments.aspx?i=" & User1.ProviderUserKey.ToString & "&j=" & ImageButton1.CommandArgument)
00033:     End Sub
00034: 
00035:     Protected Sub ImageButton2_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButton2.Click
00036:         GridView1.DataSourceID = "GetBugList"
00037:         GridView1.DataBind()
00038:     End Sub
00039: 
00040:     Protected Sub ImageButton3_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButton3.Click, ImageButton4.Click, ImageButton5.Click, ImageButton6.Click, ImageButton7.Click, ImageButton8.Click, ImageButton9.Click, ImageButton10.Click
00041:         Dim Button1 As ImageButton = CType(sender, ImageButton)
00042:         GetBugList1.SelectParameters("i").DefaultValue = Button1.CommandArgument
00043:         GridView1.DataSourceID = "GetBugList1"
00044:         GridView1.DataBind()
00045:     End Sub
00046: End Class

Вторая форма



00001: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="BugAdd.aspx.vb" Inherits="BugAdd" %>
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>Баг-трекер</title>
00008: </head>
00009: <body>
00010:     <form id="form1" runat="server">
00011:     <div>
00012:         <div style="text-align:center; font-size:20px">
00013:         <asp:HyperLink ID="HyperLink1" NavigateUrl="~/BugList.aspx" runat="server">Баг-трекер</asp:HyperLink> ->
00014:          Добавление нового описания бага или задачи</div>
00015: <div style="height:10px"></div>
00016: <table width=100%&gt;
00017: &lt;tr><td> &nbsp;</td></tr>
00018: <tr><td>URL странички с ошибкой: </td></tr>
00019: <tr><td>
00020:     <asp:TextBox ID="TextBox1" Width=100% runat="server"></asp:TextBox> </td></tr>
00021: <tr><td> &nbsp;</td></tr>
00022: <tr><td>Подробное описание проблемы </td></tr>
00023: <tr><td><asp:TextBox ID="TextBox2" Width=100% runat="server" MaxLength="4000" 
00024:         Rows="10" TextMode="MultiLine"></asp:TextBox></td></tr>
00025: <tr><td> &nbsp;</td></tr>
00026: <tr><td>Рисунок: </td></tr>
00027: <tr><td> 
00028:     <asp:FileUpload ID="FileUpload1" runat="server" Width="100%" />
00029:     </td></tr>
00030:     <tr><td> &nbsp;</td></tr>
00031: </table>
00032: <div style="height:10px"></div>
00033: <table><tr><td>
00034:     <asp:ImageButton ID="ImageButton1" ImageUrl="~/BugImage/Add.gif" ToolTip="Добавить баг" runat="server" 
00035:             Height="50px" Width="50px"  />
00036: 
00037: </td><td>Добавить баг</td></tr></table>
00038: 
00039: 
00040:     </div>
00041:         <asp:SqlDataSource ID="AddBug" runat="server" 
00042:             ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00043:             SelectCommand="INSERT [Bugs] ([ToState],[TXT],[Page],[ToImage],[CrDate],[ToUser]) Values (1,@TXT,@Page,@ToImage, GetDate(), @ToUser)">
00044:             <SelectParameters>
00045:                 <asp:ControlParameter ControlID="TextBox2" Name="TXT" PropertyName="Text" />
00046:                 <asp:ControlParameter ControlID="TextBox1" Name="Page" PropertyName="Text" />
00047:                 <asp:Parameter Name="ToImage" Type="String"  />
00048:                 <asp:Parameter Name="ToUser" Type="String" />
00049:             </SelectParameters>
00050:         </asp:SqlDataSource>
00051:     </form>
00052: </body>
00053: </html>

00001: Partial Class BugAdd
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub BugAdd_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00005:         If Not IsPostBack Then
00006:             If User.Identity.Name = "" Then Response.Redirect("~/Default.aspx")
00007:             TextBox1.Focus()
00008:         End If
00009:     End Sub
00010: 
00011:     Protected Sub ImageButton1_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButton1.Click
00012:         Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00013:         If FileUpload1.FileName <> "" Then
00014:             Dim ImageName As String = Guid.NewGuid.ToString
00015:             FileUpload1.SaveAs(System.IO.Path.Combine(Server.MapPath("~/BugImage"), ImageName & ".gif"))
00016:             AddBug.SelectParameters("ToImage").DefaultValue = ImageName & ".gif"
00017:         Else
00018:             AddBug.SelectParameters("ToImage").DefaultValue = "нет"
00019:         End If
00020:         If TextBox1.Text = "" Then AddBug.SelectParameters("Page").DefaultValue = " "
00021:         If TextBox2.Text = "" Then AddBug.SelectParameters("TXT").DefaultValue = " "
00022:         AddBug.SelectParameters("ToUser").DefaultValue = CurUser.ProviderUserKey.ToString
00023:         AddBug.Select(New DataSourceSelectArguments)
00024:         Response.Redirect("~/BugList.aspx")
00025:     End Sub
00026: End Class

Третья форма.



00001: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="BugChange.aspx.vb" Inherits="BugChange" %>
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>Баг-трекер</title>
00008: </head>
00009: <body>
00010:     <form id="form1" runat="server">
00011:     <div>
00012:     <div style="text-align:center; font-size:20px">
00013:         <asp:HyperLink ID="HyperLink1" NavigateUrl="~/BugList.aspx" runat="server">Баг-трекер</asp:HyperLink> ->
00014:         <asp:HyperLink ID="HyperLink2" runat="server">История</asp:HyperLink> ->
00015:         Сохраните ваше сообщение, установив текущее состояние проблемы.</div>
00016: 
00017: <table width="100%">
00018: <tr><td> &nbsp;</td></tr>
00019: <tr><td><asp:TextBox ID="TextBox1" Width=100% runat="server" MaxLength="4000" 
00020:         Rows="10" TextMode="MultiLine"></asp:TextBox></td></tr>
00021: <tr><td> &nbsp;</td></tr>
00022: <tr><td>При необходимости подкрепите ваше мнение рисунком: </td></tr>
00023: <tr><td> 
00024:     <asp:FileUpload ID="FileUpload1" runat="server" Width="100%" />
00025:     </td></tr>
00026:     <tr><td> &nbsp;</td></tr>
00027: </table>
00028: 
00029:         <table width="100%">
00030:       <tr><td align="left" valign="top">
00031:         <asp:ImageButton ID="ImageButton1" ImageUrl="~/BugImage/Mail.gif"  
00032:               CommandArgument="2"  runat="server" Height="50px" Width="50px" />
00033:         </td><td style="font-size:14px">Обсуждение и уточнение задачи.
00034:         </td></tr>    
00035:       <tr><td align="left" valign="top">
00036:         <asp:ImageButton ID="ImageButton2" ImageUrl="~/BugImage/Time.gif"  CommandArgument="3" 
00037:               runat="server" Height="50px" Width="50px" />
00038:         </td><td style="font-size:14px">Решение задачи отложено на более позднее время.
00039:         </td></tr>
00040:     <tr><td align=left valign=top style="font-size:14px">
00041:         <asp:ImageButton ID="ImageButton3" ImageUrl="~/BugImage/Close.gif" CommandArgument="4"  runat="server" Height="50px" Width="50px" /></td><td style="font-size:14px">
00042:             Задача не может быть выполнена:<br />
00043:             <ul>
00044:             <li style="font-size:12px">Это заведомо предусмотренное штатное поведение данной программы. Изменение этого поведения противоречит уже принятым и реализованным проектным решениям.</li>
00045:             <li style="font-size:12px">Данная программа не предназначена для решения этой задачи.</li>
00046:             <li style="font-size:12px">Решение этой задачи выходит за рамки технологии ASP NET.</li>
00047:             <li style="font-size:12px">Это снижает юзабилити, поведение программы становится неожиданным и непонятным в глазах пользователя.</li>
00048:             <li style="font-size:12px">Решение этой задачи слишком сложно. Программа становится слишком громоздкой, неуправляемой и трудно сопровождаемой.</li>
00049:             <li style="font-size:12px">Это стандартное поведение серверной среды программирования ASP NET, WEB-сервера, SQL-сервера, браузера.</li>
00050:             <li style="font-size:12px">Этот вопрос не в компетенции программиста. Следует обратится к верстальщику, дизайнеру, контент-менеджеру, SQL-программисту, администратору, модератору.
00051:             </ul> 
00052:       </td></tr>    
00053:         <tr><td align="left" valign="top">
00054:         <asp:ImageButton ID="ImageButton4" ImageUrl="~/BugImage/Write.gif" CommandArgument="5"  runat="server" Height="50px" Width="50px" />
00055:         </td><td style="font-size:14px">Задача полностью понятна и взята программистом в разработку.
00056:         </td></tr>
00057:             <tr><td align="left" valign="top">
00058:         <asp:ImageButton ID="ImageButton5" ImageUrl="~/BugImage/Atten.gif" CommandArgument="6"  runat="server" Height="50px" Width="50px" />
00059:         </td><td style="font-size:14px">Обработка проблемы программистом завершена!
00060:         </td></tr>
00061:            
00062:         <tr><td align="left" valign="top">    
00063:          <asp:ImageButton ID="ImageButton6" ImageUrl="~/BugImage/Quest.gif"  CommandArgument="7"  runat="server" Height="50px" Width="50px" />
00064:         </td><td style="font-size:14px">Решение задачи не найдено, непонятно или не соответствует поставленной задаче.
00065:         </td></tr>
00066:           <tr><td align="left" valign="top">   
00067:         <asp:ImageButton ID="ImageButton7" ImageUrl="~/BugImage/OK.gif" CommandArgument="8"  runat="server" Height="50px" Width="50px" />
00068:         </td><td style="font-size:14px">Решение задачи перепроверено, принято и проблема полностью закрыта.
00069:         </td></tr>
00070:             
00071:     </table>
00072:     </div>
00073:     <asp:SqlDataSource ID="AddComment" runat="server" 
00074:         ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00075:         SelectCommand="INSERT [BugComment] ([ToBug] , [ToUser] ,[NewState] ,[Comment], [Date], [ToImage])  VALUES (@ToBug , @ToUser ,@NewState ,@Comment, GetDate(), @ToImage)">
00076:         <SelectParameters>
00077:             <asp:QueryStringParameter Name="ToBug" QueryStringField="j" />
00078:             <asp:QueryStringParameter Name="ToUser" QueryStringField="i" />
00079:             <asp:Parameter Name="NewState"  Type="Int32" />
00080:             <asp:Parameter Name="ToImage"  Type="String" />
00081:             <asp:ControlParameter ControlID="TextBox1" Name="Comment" PropertyName="Text" />
00082:         </SelectParameters>
00083:     </asp:SqlDataSource>
00084:     
00085:     
00086:         <asp:SqlDataSource ID="SetState" runat="server" 
00087:             ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00088:             SelectCommand="update Bugs set ToState=@NewState where i=@i">
00089:             <SelectParameters>
00090:                 <asp:Parameter Name="NewState" Type="Int32" />
00091:                 <asp:QueryStringParameter Name="i" QueryStringField="j" />
00092:             </SelectParameters>
00093:         </asp:SqlDataSource>
00094:     
00095:     
00096:     </form>
00097: </body>
00098: </html>

00001: Partial Class BugChange
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub BugChange_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00005:         If Not IsPostBack Then
00006:             If User.Identity.Name = "" Then Response.Redirect("~/Default.aspx")
00007:             Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00008:             HyperLink2.NavigateUrl = "~/BugComments.aspx?i=" & CurUser.ProviderUserKey.ToString & "&j=" & Request.QueryString("j")
00009:             HyperLink2.Text = "История задачи # " & Request.QueryString("j")
00010:             TextBox1.Focus()
00011:         End If
00012:     End Sub
00013: 
00014:     Protected Sub ImageButton1_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButton1.Click, ImageButton2.Click, ImageButton3.Click, ImageButton4.Click, ImageButton5.Click, ImageButton6.Click, ImageButton7.Click
00015:         Dim Button1 As ImageButton = CType(sender, ImageButton)
00016:         'при желании это можно в транзакцию обьединить
00017:         If FileUpload1.FileName <> "" Then
00018:             Dim ImageName As String = Guid.NewGuid.ToString
00019:             FileUpload1.SaveAs(System.IO.Path.Combine(Server.MapPath("~/BugImage"), ImageName & ".gif"))
00020:             AddComment.SelectParameters("ToImage").DefaultValue = ImageName & ".gif"
00021:         Else
00022:             AddComment.SelectParameters("ToImage").DefaultValue = "нет"
00023:         End If
00024:         If TextBox1.Text = "" Then AddComment.SelectParameters("Comment").DefaultValue = " "
00025:         AddComment.SelectParameters("NewState").DefaultValue = Button1.CommandArgument
00026:         AddComment.Select(New DataSourceSelectArguments)
00027:         SetState.SelectParameters("NewState").DefaultValue = Button1.CommandArgument
00028:         SetState.Select(New DataSourceSelectArguments)
00029:         Response.Redirect("~/BugList.aspx")
00030:     End Sub
00031: 
00032: End Class

Четвертая форма



00001: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="BugComment.aspx.vb" Inherits="BugComment" %>
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>Баг-трекер</title>
00008: </head>
00009: <body>
00010:     <form id="form1" runat="server">
00011:     <div>
00012:     
00013:        <div>
00014:         <div style="text-align:center; font-size:20px">
00015:             <asp:HyperLink ID="HyperLink1" NavigateUrl="~/BugList.aspx" runat="server">Баг-трекер</asp:HyperLink> ->
00016:             <asp:HyperLink ID="Label1" runat="server" ></asp:HyperLink> -> 
00017:             <asp:Label ID="Label2" runat="server" ></asp:Label></div> 
00018:      <div style="height:10px"></div>
00019:         <table width="100%">
00020:     <tr><td>
00021:         <asp:Image ID="Image2" Width="50" Height="50" runat="server" />
00022:     </td><td>
00023:         <asp:Label ID="Label3" runat="server" ></asp:Label></td></tr>    
00024:     <tr><td colspan="2">
00025:         <asp:Image ID="Image1" runat="server" /></td></tr>
00026:     </table>
00027:      <div style="height:10px"></div>
00028:         <table><tr><td>
00029:     <asp:ImageButton ID="ImageButton2" runat="server" Height="50px" 
00030:         ImageUrl="~/BugImage/Circle.gif" 
00031:         ToolTip="Добавить сообщение или изменить состояние." Width="50px" />
00032:     </td><td>
00033:     Добавить сообщение или изменить состояние.</td>
00034:     </tr></table>
00035:     </div>
00036:     
00037:     </form>
00038:         <asp:SqlDataSource ID="GetOneComment" runat="server" 
00039:         ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00040:         SelectCommand="select BugComment.*,BugState.Image,BugState.Descr from BugComment join BugState on BugState.i=BugComment.NewState where BugComment.i=@i">
00041:         <SelectParameters>
00042:             <asp:QueryStringParameter Name="i" QueryStringField="k"  Type="String"  />
00043:         </SelectParameters>
00044:     </asp:SqlDataSource>
00045: 
00046:     
00047: </body>
00048: </html>

00001: Partial Class BugComment
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub BugChange_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00005:         If Not IsPostBack Then
00006:             If User.Identity.Name = "" Then Response.Redirect("~/Default.aspx")
00007:             Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00008:             Label1.Text = "История задачи # " & Request.QueryString("j")
00009:             Label1.NavigateUrl = "~/BugComments.aspx?i=" & CurUser.ProviderUserKey.ToString & "&j=" & Request.QueryString("j")
00010:             Label2.Text = "Комментарий # " & Request.QueryString("k")
00011:             Dim DV1 As Data.DataView = GetOneComment.Select(New DataSourceSelectArguments)
00012:             If DV1 IsNot Nothing Then
00013:                 If DV1.Count > 0 Then
00014:                     If IsDBNull(DV1(0)("ToImage")) Then
00015:                         Image1.Visible = False
00016:                     Else
00017:                         If DV1(0)("ToImage") <> "нет" Then
00018:                             Image1.ImageUrl = "~/BugImage/" & DV1(0)("ToImage")
00019:                         End If
00020:                     End If
00021:                     Image2.ImageUrl = "~/BugImage/" & DV1(0)("Image")
00022:                     Image2.ToolTip = DV1(0)("Descr")
00023:                     Label3.Text = DV1(0)("Comment")
00024:                 End If
00025:             End If
00026:         End If
00027:     End Sub
00028: 
00029:     Protected Sub ImageButton2_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButton2.Click
00030:         Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00031:         Response.Redirect("~/BugChange.aspx?i=" & CurUser.ProviderUserKey.ToString & "&j=" & Request.QueryString("j"))
00032:     End Sub
00033: End Class

Пятая форма



00001: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="BugComments.aspx.vb" Inherits="BugComments" %>
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>Баг-трекер</title>
00008: </head>
00009: <body>
00010:     <form id="form1" runat="server">
00011:     <div>
00012:         <div style="text-align:center; font-size:20px">
00013:             <asp:HyperLink ID="HyperLink1" NavigateUrl="~/BugList.aspx" runat="server">Баг-трекер</asp:HyperLink> ->
00014:             <asp:Label ID="Label4" runat="server" ></asp:Label></div>
00015:     <div style="height:10px"></div>
00016:     <table width="100%">
00017:     <tr><td>
00018:         <asp:Label ID="Label2" runat="server" ></asp:Label></td></tr>    
00019:     <tr><td>
00020:         <asp:HyperLink ID="HyperLink3" runat="server"></asp:HyperLink></td></tr>
00021:     <tr><td>
00022:         <asp:Image ID="Image1" runat="server" /></td></tr>
00023:      <tr><td>
00024:         <asp:Label ID="Label3" runat="server" ></asp:Label></td></tr>   
00025:     </table>
00026:     <div style="height:10px"></div>
00027:     <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
00028:         AutoGenerateColumns="False" DataMember="DefaultView"  DataKeyNames="i"
00029:         DataSourceID="GetComment" PageSize="20" Width="100%">
00030:         <Columns>
00031:             <asp:TemplateField HeaderText="State">
00032:                 <ItemTemplate>
00033:                     <asp:ImageButton ID="ImageButton1" Width="50" Height="50" runat="server" CommandArgument='<%# Eval("i") %>' />
00034:                 </ItemTemplate>
00035:             </asp:TemplateField>
00036:             <asp:TemplateField >
00037:                 <ItemTemplate>
00038:                     <asp:Label ID="KTO" runat="server"></asp:Label>
00039:                 </ItemTemplate>
00040:             </asp:TemplateField>
00041:             <asp:TemplateField HeaderText="Bug/Task">
00042:                 <ItemTemplate>
00043:                     <asp:HyperLink ID="HyperLink2" runat="server" Text='<%# Eval("Comment") %>'></asp:HyperLink>
00044:                 </ItemTemplate>
00045:             </asp:TemplateField>
00046: 
00047:         </Columns>
00048:     </asp:GridView>
00049:     <div style="height:10px"></div>
00050:     <table><tr><td>
00051:     <asp:ImageButton ID="ImageButton2" runat="server" Height="50px" 
00052:         ImageUrl="~/BugImage/Circle.gif" 
00053:         ToolTip="Добавить сообщение или изменить состояние." Width="50px" />
00054:     </td><td>
00055:     Добавить сообщение или изменить состояние.</td>
00056:     </tr></table>
00057:     </div>
00058:     <asp:SqlDataSource ID="GetBug" runat="server" 
00059:         ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00060:         SelectCommand="select * from Bugs join BugState on Bugs.ToState=BugState.i where Bugs.i=@i">
00061:         <SelectParameters>
00062:             <asp:QueryStringParameter Name="i" QueryStringField="j" Type="String" />
00063:         </SelectParameters>
00064:     </asp:SqlDataSource>
00065:     <asp:SqlDataSource ID="GetComment" runat="server" 
00066:         ConnectionString="<%$ ConnectionStrings:SQLServer_ConnectionStrings %>" 
00067:         SelectCommand="select BugComment.*,BugState.Image,BugState.Descr from BugComment join BugState on BugState.i=BugComment.NewState where ToBug=@i order by BugComment.i">
00068:         <SelectParameters>
00069:             <asp:QueryStringParameter Name="i" QueryStringField="j"  Type="String"  />
00070:         </SelectParameters>
00071:     </asp:SqlDataSource>
00072:     </form>
00073: </body>
00074: </html>

00001: Partial Class BugComments
00002:     Inherits System.Web.UI.Page
00003: 
00004:     Protected Sub BugChange_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00005:         If Not IsPostBack Then
00006:             If User.Identity.Name = "" Then Response.Redirect("~/Default.aspx")
00007:             Label4.Text = "История задачи # " & Request.QueryString("j")
00008:             Dim DV1 As Data.DataView = GetBug.Select(New DataSourceSelectArguments)
00009:             Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00010:             If DV1 IsNot Nothing Then
00011:                 If DV1.Count > 0 Then
00012:                     HyperLink3.Text = DV1(0)("Page") : HyperLink3.NavigateUrl = DV1(0)("Page")
00013:                     Dim User1 As MembershipUser = Membership.GetUser(DV1(0)("ToUser"))
00014:                     Label2.Text = User1.UserName & " (" & DV1(0)("CrDate") & ")"
00015:                     Label3.Text = DV1(0)("TXT")
00016:                     If IsDBNull(DV1(0)("ToImage")) Then
00017:                         Image1.Visible = False
00018:                     Else
00019:                         If DV1(0)("ToImage") = "нет" Then
00020:                             Image1.Visible = False
00021:                         Else
00022:                             Image1.ImageUrl = "~/BugImage/" & DV1(0)("ToImage")
00023:                         End If
00024:                     End If
00025: 
00026:                 End If
00027:             End If
00028:         End If
00029:     End Sub
00030: 
00031:     Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
00032:         If e.Row.DataItem IsNot Nothing Then
00033:             Dim KTO As Label = CType(e.Row.FindControl("KTO"), Label)
00034:             Dim User1 As MembershipUser = Membership.GetUser(e.Row.DataItem("ToUser"))
00035:             KTO.Text = User1.UserName & " (" & e.Row.DataItem("Date") & ")"
00036:             Dim ImageButton1 As ImageButton = CType(e.Row.FindControl("ImageButton1"), ImageButton)
00037:             ImageButton1.ToolTip = e.Row.DataItem("Descr")
00038:             ImageButton1.ImageUrl = "~/BugImage/" & e.Row.DataItem("Image")
00039:             Dim HyperLink2 As HyperLink = CType(e.Row.FindControl("HyperLink2"), HyperLink)
00040:             If Not IsDBNull(e.Row.DataItem("ToImage")) Then
00041:                 If e.Row.DataItem("ToImage") <> "нет" Then
00042:                     ImageButton1.PostBackUrl = "~/BugComment.aspx?i=" & User1.ProviderUserKey.ToString & "&j=" & Request.QueryString("j") & "&k=" & e.Row.DataItem("i")
00043:                     HyperLink2.NavigateUrl = "~/BugComment.aspx?i=" & User1.ProviderUserKey.ToString & "&j=" & Request.QueryString("j") & "&k=" & e.Row.DataItem("i")
00044:                 End If
00045:             End If
00046:         End If
00047:     End Sub
00048: 
00049: 
00050:     Protected Sub ImageButton2_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButton2.Click
00051:         Dim CurUser As MembershipUser = Membership.GetUser(User.Identity.Name)
00052:         Response.Redirect("~/BugChange.aspx?i=" & CurUser.ProviderUserKey.ToString & "&j=" & Request.QueryString("j"))
00053:     End Sub
00054: 
00055: End Class

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

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






Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: //www.vb-net.com/asp2/37/index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>