ASP.NET 简单调查应用程序






4.87/5 (17投票s)
这种类型的需求在许多应用程序中都很有用,最初发布在 http://www.srinetinfo.com/search/label/Survey%20Application
引言
提供各种服务的公司需要以多种形式获取客户的反馈。通过分析这些反馈,公司可以对他们的服务和绩效有一个概览。
调查或投票在不同情况和组织中非常重要。例如,考虑一家公司在市场上销售不同的产品。如果他们想了解产品的使用情况和最终用户的满意度,他们会进行一次简单的用户调查。在收集了大多数公众的反馈后,他们会从不同的角度开始分析这些反馈,例如:
- 该产品在人们中的使用百分比是多少。
- 人们购买该产品的频率如何?
- 公众满意度指数等。
背景
我们有各种网站可以提供简单的问卷和答案集,然后发布或共享您的调查链接给目标群体、网络或个人。我们可以在常规应用程序中嵌入我们自己的解决方案,该解决方案将在一段时间内对组织内部人员开放填写。最后,对于普通人来说,为了共享他们的调查或投票,我们有提供有限功能的社交网站。
 
我们需要开发一个简单的应用程序,管理员可以准备问卷并创建一个简单的调查,并将其分享给在我们网站上注册的任何人。一旦最终用户填写了调查,网站管理员或任何有权访问的人都可以以图形或文本等任何形式分析调查结果和反馈。
高层设计
 
 
参与者
- 管理员:准备调查并通过邮件与注册用户共享调查的人。
- 经理:分析和准备已填写调查报告的人
- 用户:收到邮件后填写调查表的用户。
Actions
- 注册:用户最初在网站上注册
- 创建调查:管理员创建调查
- 共享调查:创建后,管理员会与最终用户共享此调查。
- 填写调查:最终用户填写并发送响应。
- 分析调查:一旦收到调查响应,经理就可以开始根据不同参数进行分析。
类图
数据库架构
使用代码
到目前为止,我们已经完成了高层设计、数据库设计和类图。现在我们一步一步地看看实际的应用程序是如何开发的。
创建数据库
创建一个名为 SurveyApp 的新数据库,如图所示。
在此数据库上使用以下脚本创建新表。
USE [SurveyApp]
GO
/****** Object:  Table [dbo].[Roles]    Script Date: 09/12/2012 15:46:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Roles](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [Name] [varchar](200) NOT NULL,
 CONSTRAINT [PK_Roles] PRIMARY KEY CLUSTERED 
(
 [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
    IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Questions]    Script Date: 09/12/2012 15:46:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Questions](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [Text] [varchar](200) NOT NULL,
 [QuestionType] [varchar](200) NOT NULL,
 [Options] [varchar](2000) NOT NULL,
 CONSTRAINT [PK_Questions] PRIMARY KEY CLUSTERED 
(
 [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
   IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Users]    Script Date: 09/12/2012 15:46:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Users](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [FirstName] [varchar](200) NOT NULL,
 [LastName] [varchar](200) NULL,
 [UserName] [varchar](200) NOT NULL,
 [Password] [varchar](200) NOT NULL,
 [Role] [int] NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
 [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
   IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Surveys]    Script Date: 09/12/2012 15:46:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Surveys](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [Title] [varchar](200) NULL,
 [Description] [varchar](200) NOT NULL,
 [CreatedOn] [datetime] NOT NULL,
 [ExpiresOn] [datetime] NULL,
 [CreatedBy] [int] NOT NULL,
 [Publish] [bit] NOT NULL,
 CONSTRAINT [PK_Surveys] PRIMARY KEY CLUSTERED 
(
 [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[SurveyResponse]    Script Date: 09/12/2012 15:46:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[SurveyResponse](
 [ID] [int] NOT NULL,
 [SurveyID] [int] NOT NULL,
 [QuestionID] [int] NOT NULL,
 [Response] [varchar](200) NOT NULL,
 [FilledBy] [int] NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Survey_Questions]    Script Date: 09/12/2012 15:46:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Survey_Questions](
 [ID] [int] NOT NULL,
 [SurveyID] [int] NOT NULL,
 [QuestionID] [int] NOT NULL,
 [OrderId] [int] NULL
) ON [PRIMARY]
GO
/****** Object:  ForeignKey [FK_Survey_Questions_Questions]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[Survey_Questions]  WITH CHECK ADD 
      CONSTRAINT [FK_Survey_Questions_Questions] FOREIGN KEY([QuestionID])
REFERENCES [dbo].[Questions] ([ID])
GO
ALTER TABLE [dbo].[Survey_Questions] CHECK CONSTRAINT [FK_Survey_Questions_Questions]
GO
/****** Object:  ForeignKey [FK_Survey_Questions_Surveys]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[Survey_Questions]  WITH CHECK ADD  
      CONSTRAINT [FK_Survey_Questions_Surveys] FOREIGN KEY([SurveyID])
REFERENCES [dbo].[Surveys] ([ID])
GO
ALTER TABLE [dbo].[Survey_Questions] CHECK CONSTRAINT [FK_Survey_Questions_Surveys]
GO
/****** Object:  ForeignKey [FK_SurveyResponse_Questions]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[SurveyResponse]  WITH CHECK ADD 
      CONSTRAINT [FK_SurveyResponse_Questions] FOREIGN KEY([QuestionID])
REFERENCES [dbo].[Questions] ([ID])
GO
ALTER TABLE [dbo].[SurveyResponse] CHECK CONSTRAINT [FK_SurveyResponse_Questions]
GO
/****** Object:  ForeignKey [FK_SurveyResponse_Surveys]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[SurveyResponse]  WITH CHECK ADD 
      CONSTRAINT [FK_SurveyResponse_Surveys] FOREIGN KEY([SurveyID])
REFERENCES [dbo].[Surveys] ([ID])
GO
ALTER TABLE [dbo].[SurveyResponse] CHECK CONSTRAINT [FK_SurveyResponse_Surveys]
GO
/****** Object:  ForeignKey [FK_SurveyResponse_Users]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[SurveyResponse]  WITH CHECK ADD  
      CONSTRAINT [FK_SurveyResponse_Users] FOREIGN KEY([FilledBy])
REFERENCES [dbo].[Users] ([ID])
GO
ALTER TABLE [dbo].[SurveyResponse] CHECK CONSTRAINT [FK_SurveyResponse_Users]
GO
/****** Object:  ForeignKey [FK_Surveys_Users]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[Surveys]  WITH CHECK ADD  CONSTRAINT [FK_Surveys_Users] FOREIGN KEY([CreatedBy])
REFERENCES [dbo].[Users] ([ID])
GO
ALTER TABLE [dbo].[Surveys] CHECK CONSTRAINT [FK_Surveys_Users]
GO
/****** Object:  ForeignKey [FK_Users_Roles]    Script Date: 09/12/2012 15:46:11 ******/
ALTER TABLE [dbo].[Users]  WITH CHECK ADD  CONSTRAINT [FK_Users_Roles] FOREIGN KEY([Role])
REFERENCES [dbo].[Roles] ([ID])
GO
ALTER TABLE [dbo].[Users] CHECK CONSTRAINT [FK_Users_Roles]
GO 
创建项目
- 在 Visual Studio 中选择新建项目。
- 选择 ASP.NET Web 应用程序模板。
- 将项目命名为 SimpleSurvey。
删除所有默认创建的文件夹,如图所示。
向项目中添加一个名为 SurveyForm.aspx 的新窗体。
添加一个名为 SurveysManager.cs 的新类。
向应用程序添加一个枚举,以便我们可以轻松地对问题进行分类。
将以下枚举添加到 SurveysManager.cs。
public enum QuestionTypes
{
    SingleLineTextBox, // will render a textbox 
    MultiLineTextBox, // will render a text area
    YesOrNo, //will render a checkbox
    SingleSelect, //will render a dropdownlist
    MultiSelect //will render a listbox
} 用于数据库接口的 Entity Framework
在这里,我们将使用 EF 进行与数据库相关的操作。只需添加一个名为 SurveyAppContext.edmx 的新文件,如下所示。
从 Visual Studio 数据模板中添加 ADO.NET Entity Model 的新项。
选择“从数据库生成模型”以继续。
选择一个连接字符串并继续。
选择数据库活动所需的表并完成。
最后,Entity Framework 将在 Visual Studio 中生成如下模型,然后生成执行实体 CRUD 操作所需的必要方法。您可以在下面的图像中查看。
模型
创建一个新的“管理问题”窗体,应如下所示。
创建一个新的“管理调查”窗体,应如下所示。
我们已经完成了“管理问题”和“管理调查”屏幕的创建。现在我们完成了要求的一半。这两个将为我们提供添加一些问题和调查的方式。
我们以用户对产品的反馈表为例。
反馈应包含以下问题。
- 名字
- 姓氏
- 用户电子邮件 ID
- 手机号码(可选)
- 评分(1 到 5)
- 注释
调查标题应为 
从“管理问题”屏幕添加所有问题。
从“管理调查”屏幕添加反馈调查。
如上一步所示,将所有问题和调查添加到数据库。
反馈表渲染
应用程序的实际部分,我们现在将讨论。
第一步:从数据库获取相应的调查定义。
我们的渲染页面将如下所示,并将列出已添加的调查数量。选择渲染示例反馈表。
最后,一旦您在下拉列表中选择了调查,它将回发并渲染带有问题和相应字段的页面,如图所示。
这是使用相应控件渲染页面的基本代码格式。
private void PopulateSurvey()
{
    List<Question> questions = (from p in context.Questions
                                join q in context.SurveyQuestions on p.ID equals q.QuestionID
                                where q.SurveyID == surveyid
                                select p).ToList();
    Table tbl = new Table();
    tbl.Width = Unit.Percentage(100);
    TableRow tr;
    TableCell tc;
    TextBox txt;
    CheckBox cbk;
    DropDownList ddl;
    foreach (Question q in questions)
    {
        tr = new TableRow();
        tc = new TableCell();
        tc.Width = Unit.Percentage(25);
        tc.Text = q.Text;
        tc.Attributes.Add("id", q.ID.ToString());
        tr.Cells.Add(tc);
        tc = new TableCell();
        if (q.QuestionType.ToLower() == "singlelinetextbox")
        {
            txt = new TextBox();
            txt.ID = "txt_" + q.ID;
            txt.Width = Unit.Percentage(40);
            tc.Controls.Add(txt);
        }
        if (q.QuestionType.ToLower() == "multilinetextbox")
        {
            txt = new TextBox();
            txt.ID = "txt_" + q.ID;
            txt.TextMode = TextBoxMode.MultiLine;
            txt.Width = Unit.Percentage(40);
            tc.Controls.Add(txt);
        }
        if (q.QuestionType.ToLower() == "singleselect")
        {
            ddl = new DropDownList();
            ddl.ID = "ddl_" + q.ID;
            ddl.Width = Unit.Percentage(41);
            if (!string.IsNullOrEmpty(q.Options))
            {
                string[] values = q.Options.Split(',');
                foreach (string v in values)
                    ddl.Items.Add(v.Trim());
            }
            tc.Controls.Add(ddl);
        }
        tc.Width = Unit.Percentage(80);
        tr.Cells.Add(tc);
        tbl.Rows.Add(tr);
    }
    pnlSurvey.Controls.Add(tbl);
}
以下是单击提交按钮后,从动态控件获取响应的代码。
private List<Survey_Response> GetSurveyReponse()
{
    List<Survey_Response> response = new List<Survey_Response>();
    foreach (Control ctr in pnlSurvey.Controls)
    {
        if (ctr is Table)
        {
            Table tbl = ctr as Table;
            foreach (TableRow tr in tbl.Rows)
            {
                Survey_Response sres = new Survey_Response();
                sres.FilledBy = 2;
                sres.SurveyID = surveyid;
                sres.QuestionID = Convert.ToInt32(tr.Cells[0].Attributes["ID"]);
                TableCell tc = tr.Cells[1];
                foreach (Control ctrc in tc.Controls)
                {
                    if (ctrc is TextBox)
                    {
                        sres.Response = (ctrc as TextBox).Text.Trim();
                    }
                    else if (ctrc is DropDownList)
                    {
                        sres.Response = (ctrc as DropDownList).SelectedValue;
                    }
                    else if (ctrc is CheckBox)
                    {
                        sres.Response = (ctrc as CheckBox).Checked.ToString();
                    }
                }
                response.Add(sres);
            }
        }
    }
    return response;
}
这是一个简单的应用程序,可以扩展以获得更多功能,并包含更多实时功能。可以下载工作代码这里。
兴趣点
这涵盖了以下概念:
动态控件、动态表单、表单反馈以及功能需求的泛化。
历史
初始版本发布于 2012 年 10 月 31 日。



















