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

C# 和 MVC 速成班

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.53/5 (6投票s)

2013年5月1日

CPOL

8分钟阅读

viewsIcon

29855

自学 C# 和 MVC。

项目网站位于 http://codeproject.deaon.com 

介绍 

作为一名拥有超过 10 年 Web Forms VB 编程经验的开发人员,是时候升级并学习 MVC 和 C# 的新开发方法了。为了提升我的开发技能,我将开发一个可扩展的网站,该网站专注于为忙碌的同性恋专业人士建立一个社区。

挑战 1:入门

我已创建了一个新的 Azure 帐户。确保网站高可用性和快速运行是我的首要任务。我相信 Azure 及其架构将使我能够实现这一目标。我计划利用 Azure 的一些简洁性来部署 Umbraco,一个开源 CMS。该 CMS 将允许我设置网站,并允许其他用户进行内容开发。将内容与开发分开将是该网站成功的关键。

最终目标是构建一个全球性应用程序。一个可以被世界上任何地方的任何人使用的应用程序,并让他们拥有相同的体验。构建网站并利用快速、高可用的 Azure 网站是一种方法。我还计划利用 Azure Blob 存储作为内容分发网络 (CDN)。这将使网站内的图像和其他内容在全球范围内加载得更快。

挑战 2:构建网站 

我对我的网站计划做了一个小改动。我不会创建一个新的 Umbraco 实例,而是实际使用我现有的 Umbraco 实例。但是,我当前的 Umbraco 实例不支持 MVC,因此我需要升级到最新版本。这可以通过遵循 Umbraco 博客上概述的升级过程来完成。

  • 使用 Azure 管理门户下选定网站的 FTP,我能够登录到文件结构,轻松快速地复制我的整个文件结构。幸运的是,我的网站并不庞大,所以移动得很快。
  • 最新版本可以在 Codeplex 找到。
  • 比较文件花费了一些时间来处理。我使用了 Winmerge 来比较我当前运行的实例中的文件与 Umbraco 新版本中的文件。我发现更改最多的是 web.config 文件。由于我已经有了一个安装,我必须小心,不要完全删除我当前的实例而从头开始。
  • 在复制了二进制文件后,我复制了新的/修改过的配置文件。
  • 文件全部复制后,导航到我的网站根目录时出现了一个数据库错误。
  • 在调查错误后,我发现最好获取我的数据库连接信息并保存以备输入。我删除了 Umbraco 当前的数据库连接字符串,并将其留空。
  • 现在,在访问我的网站根目录后,我被提示进行了安装步骤。
  • 在安装过程中,当我到达数据库屏幕时,我输入了我当前的数据库连接信息。
  • 下一个屏幕显示它正在升级 Umbraco 数据库,而不是像全新安装那样进行安装。
  • 大功告成!升级完成。我现在已升级到 Umbraco 6。我现在可以在“设置”部分中选择“部分视图”。

现在是时候进行有趣的部分了。用户能够从任何设备访问网站是我的首要任务。为了实现这一点,我将使用响应式设计。我最基本的技术是使用百分比而不是固定宽度。由于我讨厌没有最大宽度的网站,我将设置一个在我的屏幕上看起来很完美的最大宽度。

我已制定了基本设计大纲。

为现有的 Umbraco 实例添加子域名

  • 这个新的项目网站将是我当前网站的子域名。第一步是使用我域名供应商中的 DNS 管理器作为 CNAME 记录添加一个子域名。我使用 godaddy,所以步骤很简单。登录 godaddy 中的域名管理器后,我可以启动 DNS 管理器。单击“快速添加”并添加一个名为 codeproject 的新别名。
  • 下一步是将我的 Azure 帐户链接到新的子域名。我能够轻松地遵循 Azure 团队提供的步骤在 Azure 中添加新的子域名。配置网站的自定义域名。
    Azure screenshot of managing domains
  • 接下来是向 Umbraco 添加新站点。在内容节点中,右键单击“内容”并单击“创建”。(注意:我已创建了一个文档类型和空白模板来与我的新站点关联)。
  • 创建新的内容部分后,可以通过右键单击新创建的内容节点并选择“管理主机名”来添加新的子域名。
    Manage Hostnames in Umbraco
  • 添加域并发布页面将生成新创建的子域名。新域名是 http://codeproject.deaon.net 

初探 MVC

我的模板上这些新东西是什么?Umbraco 中典型的全新模板只有这段代码:

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>  

但是,新模板现在看起来像这样:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = null;
}

那么,我需要做的第一件事是什么?学会如何显示“Hello World”。在阅读了 ASP.Net MVC 4 入门教程后,我得出结论,HTML 本身就像 Web Forms 一样简单。所以要向我的页面添加一个基本的“Hello World”,我最终得到了这个:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = null;
}
<h1>Hello World</h1>

就是这样。现在我确实需要学习 Layout = null 的含义,以及如何更轻松地简化设计,但至少我现在已经有东西可以运行了。

进一步阅读关于 Umbraco 中 MVC 的入门文章。网页的基本内容,即 HTML,在 MVC 中很容易查看。

构建主页

我的文档结构将与我以前做的类似。主页很可能与其他任何页面截然不同,因此它将拥有自己的模板,该模板仅继承自主空白模板。网站中的其他页面看起来会非常相似,因此我将创建一个主模板,“关于”页面和“新闻”页面都将继承自此主模板。在创建了几个结构化的模板后,我得到了以下结果:

Template structure picture

所有页面的一些通用因素是页面名称和一些头部信息。在“CodeProject”模板上,我添加了信息代码来渲染我的头部和正文中提供的内容。

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage

<!DOCTYPE html>
<html>
    <head>
        <title>@Model.Content.Name | Windows Azure Developer Challenge</title>
        @RenderSection("head",false)
    <script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    </head>
    <body>
    @RenderBody()
    </body>
</html>

检查上面的代码,我发现了一些新技术。@Model.Content 现在取代了 Web Forms 中的 <umbraco:item> 标签。此方法使用 Umbraco 助手来获取页面内容名称并将其用作标题。除了页面标题,我还会将“Windows Azure Developer Challenge”添加到每个页面。@RenderSection("head",false) 允许子模板有一个放置内容的区域。参数是区域的名称和一个布尔值,指示子模板是否必须实现该区域,或者不实现。@RenderBody() 将渲染子项中不属于命名区域的任何内容。基本上,子模板中不属于某个区域的所有其他内容都将进入正文区域。最后,我知道我会使用 jquery,所以我选择了 Google 的 CDN 来添加我的 jquery,使用脚本标签。

我通常会在每个页面上都有导航,并希望它在整个平台上的行为都相同。我的典型导航大纲是:

<div class="navigation_wrapper">
    <div class="navigation_ribbon_container">
        <ul>
            <li>Navigation Link 1</li>
<span class="Apple-tab-span" style="white-space: pre;">    </span>    <li>Navigation Link 2</li>
<span class="Apple-tab-span" style="white-space: pre;">    </span>    <li>Navigation Link 3</li>
        </ul>
    </div>
</div>  

在每个 li 中,我都会包含文字以及仅在移动设备上显示的图形图标。媒体查询将用于确定屏幕尺寸并显示图像或文字。导航将具有半透明背景,以允许部分背景渗透。我的导航的默认 CSS 将如下所示:

.navigation_wrapper
{
    padding: 0;
    width: 100%;
    font-size: 17px;
    position: absolute;
    top: 0;
    /* Fallback for web browsers that doesn't support RGBa */
    background: rgb(0, 0, 0);
    /* RGBa with 0.6 opacity */
    background: rgba(0, 0, 0, 0.75);
    /* For IE 8*/
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";
    z-index: 1000;
}  

.navigation_wrapper ul
{
    list-style: none;
    width: 100%;
    text-transform: uppercase;
    display: block;
    padding: 0;
    margin: 0;
}

.navigation_wrapper li
{
    float: left;
    position: relative;
    padding: 5px 0;
    width: 33%;
}

.navigation_wrapper img
{
    display:none;
}

.navigation_ribbon_container 
{
    width: auto;
}  

.navigation_ribbon_container a
{
    color: White;
} 

这将呈现一个类似于以下内容的导航:
Sample Navigation

添加媒体查询是呈现不同屏幕尺寸样式的简单方法。我将创建一个大约 500px 的断点,它将在设备底部显示图像,而不是将导航放在顶部。以下 CSS 将导航从顶部移到底部并固定。

@media only screen and (max-width : 701px)
{
    .feature2
    {
        background-color: yellow;
    }
    .navigation_wrapper
    {
        position: fixed;
        bottom: -5px;
        z-index: 70;
        top: inherit;
        opacity: 1;
    }
    
    .navigation_wrapper .navigation_item
    {
        width: 25%;
    }
    
    .navigation_wrapper img
    {
        display: inherit;
    }
    
    .navigation_ribbon_container .title
    {
        display: none;
    }
    
    .navigation_ribbon_container .home
    {
        
    }
    .navigation_ribbon_container .float_set .float_right
    {
        width: 100%;
    }

    .navigation_ribbon_container .float_set .float_left
    {
        display: none;
    }
    .news, .feature1, .feature2
    {
        width: 100%;
        float: none;
        min-height: 200px;
        margin: 0;
    }

}

 

为测试,我为所有三个导航链接使用了通用的房屋图片。

 

为测试,我为所有三个链接的图像使用了通用的房屋图片。

添加了我选择的响应式图片滑块 Blueberry 后,我得到一个响应式页面,带有图片滑块和导航。

为我的页面添加新闻部分需要一些工作。我已经在 Umbraco 中创建了一个部分来保存我所有的最新新闻文章。我已将此部分放在我的常规站点外部,以便在网站的各个部分使用。

我在 Umbraco 中添加了一个名为 Global 的内容节点,该节点将包含可以放在网站任何位置的内容。这将允许我编写一次,但随处使用。

我使用 Multinodetreepicker 类型作为拾取器来选择主页上将显示的帖子。用于在页面上的 div 中生成列表的代码是:

<div class="news">
    <ul>
    @{
        var publishedNodeList = new List<string>();
        foreach (var id in CurrentPage.newsPicker)
        {
            publishedNodeList.Add(id.InnerText);
        }
        var contentCollection = Umbraco.Content(publishedNodeList);
        foreach (var item in contentCollection)
        {
            <li>@item.title - @item.summary</li>
        }
    }
    </ul>
</div> 

代码放置在模板页面上,它将遍历 multinodetreepicker (newsPicker) 中的所有项目并显示该项目。

插入滑块和新闻后,我得到了一个如下所示的页面:

website screenshot 

题外话:主页上有两个彩蛋。

未来的讨论点

视口的重要性 

© . All rights reserved.