65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 MVC5 和 Razor 的投票控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (21投票s)

2014年5月14日

CPOL

3分钟阅读

viewsIcon

22520

downloadIcon

857

用于 MVC5 项目的简单投票控件,使用局部视图

引言

这是一个用于 MVC 项目的简单投票控件。 它被实现为一个局部视图,因此可以在任何需要的地方包含它。 它是使用 MVC5 在 Visual Studio 2013 中创建的。

背景

我最初写了一篇描述使用 MVC2 的投票控件的文章。 我觉得将其更新为使用 MVC5 和 Razor 是个好主意。 我首先在 Visual Studio 2013 中创建一个新的 ASP.NET Web 应用程序项目。 我在 Visual Studio 2008 中打开了原始的 MVC2 项目(它无法在 VS2013 中转换),并根据需要复制了文件。 首先假设我已经完成了所有更改,并且一切正常。 这样我就可以向你展示如何使用代码,并查看它的外观。 在本文的后面,我将描述它的工作原理以及我如何从 MVC2 版本移植它。

使用代码

在默认的 Index.aspx 页面中,我删除了主 div 的现有内容,并将其替换为以下内容:

<div class="row">
    <div style="float:left">
        @{
            VoteDataModel petModel = (VoteDataModel)ViewData[VoteDataModel.GetViewDataName("Pet")];
            petModel.ControlWidth = 200;
            Html.RenderPartial("VoteControl", petModel);
        }
    </div>
    <p style="width:300px;padding-left:10px;overflow:hidden">
        This is a simple control with a width of 200px. Click on the button to vote,
        or click <b>Skip to Results</b> to see the results without voting.
    </p>
    <div style="clear:both"></div>
    <p>
        This next control has a long question and long answers. The width has been set
        to 400px.
    </p>
    @{
        VoteDataModel longQuestionModel = (VoteDataModel)ViewData[VoteDataModel.GetViewDataName("LongQuestionsAndAnswers")];
        longQuestionModel.ControlWidth = 400;
        Html.RenderPartial("VoteControl", longQuestionModel);
    }
    <p>
        You can get back to the questions by clicking on the <b>Back to Voting</b>
        link, or see the actual number of votes (instead of the percentages) by
        clicking on <b>Show Counts</b>
    </p>
</div>

在此示例中,我们显示了两个投票控件。 你可以看到我们如何指定控件的外观(在本例中仅为宽度,但我们可以添加我们想要的任何自定义项)以及从何处获取数据。 数据 - 问题、答案和投票计数都存储在单个 XML 文件中。

我们需要在文件顶部添加对模型命名空间的引用

@using VoteControlWebApp.Models

需要修改控制器(在本例中为 HomeController.cs)以创建模型

public ActionResult Index()
{
    VoteDataModel model = new VoteDataModel("Pet", Request.PhysicalApplicationPath + "App_Data\\");
    model.Open();
    ViewData[model.ViewDataName] = model;
    model = new VoteDataModel("LongQuestionsAndAnswers", Request.PhysicalApplicationPath + "App_Data\\");
    model.Open();
    ViewData[model.ViewDataName] = model;

    return View();
} 

整个页面(在两个投票中都投票后)看起来像

因此,在了解了如何使用它之后,让我们回到我是如何实现它的。

投票控件的实现

该控件本身在 Views::Shared 文件夹中实现为一个局部视图 - VodeControl.cshtml。 所有数据都作为模型传递 - Models 文件夹中的 VoteModel.cs。

包含每个投票控件实例的数据的 XML 文件位于 App_Data 文件夹中。 每个投票控件实例都有一个 XML 文件。

有一个控制器 - VoteController.cs,位于 Controllers 文件夹中。 它的唯一目的是在单击“投票”按钮时处理传入的请求。 为了通过 VoteController 路由请求,以下路由已添加到 RouteConfig.cs 文件中

routes.MapRoute(
    "VoteButton", // Route name
    "DoVote/{uniqueName}/{voteId}", // URL with parameters
    new { controller = "Vote", action = "DoVote" },
    new { voteId = @"\d{1,3}" } // voteId can only be numeric, and less than 1000
);

投票控件需要一个样式表和 javascript(在 Content 和 Scripts 文件夹中),因此我在 _Layout.cshtml 中添加了对它们的引用。

我必须创建或修改的整个文件列表如下所示

幕后

大部分代码都在模型中(应该如此)。

VodelDataModel 对象包含答案列表 (List<AnswerItem>) 和 IP 地址列表 (List<IpAddressItem>)。 每个答案都有一个 AnswerItem,并且为每个唯一的客户端 IP 地址添加一个条目。 这就是我们确保用户只能投票一次的方式。 它并不完美 - 有关此的更多详细信息,请参阅 MVC2 文章中的“兴趣点”。

以下 public 方法在模型中可用

static string GetViewDataName(string uniqueName) and string ViewDataName

这获取将用于视图数据的名称。 我们在控制器和视图中使用它 - 在视图中有一个 static 方法,在控制器中使用一个实例属性。

public VoteDataModel(string name, string path)

对象构造函数。

public bool Open()

构造对象后应始终调用 Open。 这从 XML 文件读取数据。

public bool DoVote(int voteId, string ipAddr)

线程安全 - 请参阅上一节。

这会更新对象和文件。 如果接受了投票,则返回 true,如果找到了 ip 地址,则返回 false - 即,用户已投票。

public int GetPercentage(int index)

这在局部视图中用于显示百分比。

public int GetBarLength(int index, int controlWidth)

这在局部视图中用于显示百分比条。

关注点

从 MVC2 转换代码相对简单。 视图需要做最多的工作 - 转换为 Razor 语法,并且存在一些样式表问题。 模型不需要修改。

历史

  • 2014 年 5 月 - 初始版本
© . All rights reserved.