《Pro ASP.NET MVC 3 Framework》学习笔记之三十五 【部署】

简介:

准备要部署的应用程序

在正式进入部署MVC程序到IIS之前,会介绍一些关于应用程序迁移到生产环境之前探测错误以及一旦进入生产环境最大化性能的技术。同时也会展示关于流线型部署过程的有用的功能。

 

检测视图错误

Razor视图会在服务器需要的时候编译而不是在VS里面生成项目时编译,正常情况下,探测视图编译错误的方式是系统的访问每一个action,从而让每一个view都能够呈现。这显然是非常乏味而且不会一直成功的技术,特别是在基于不同的model状态呈现不同的view的时候。
我们可以启用一个特别的项目选项来启用我们的视图并且报告任何编译错误。我们可以编辑一个.csproj的文件,设置MvcBuildViews为true,如下:
... 
  <PropertyGroup> 
    .....
    <MvcBuildViews>true</MvcBuildViews> 
  </PropertyGroup> 
... 
这样保存以后,任何编译错误都会显示出来了。注意,这种方式只是检查编译错误,不能检测逻辑错误并且不能用来替代严格的测试体制。

 

配置动态页编译(Configuring Dynamic Page Compilation)

Web.config里面一个重要的配置是compilation节,如下:
<configuration> 
    <!-- other settings removed for clarity --> 
    <system.web> 
        <compilation debug="true" targetFramework="4.0"> 
        <assemblies> 
            <add assembly="System.Web.Abstractions, Version=4.0 ... 
            ...


在前面提到过,Razor视图是在运行时编译成.NET类的。这里的compilation配置节决定是在debug模式还是release模式执行,在开发过程中倾向于使用debug模式,该模式会让编译器做如下工作:
1.忽略代码优化以至于让编译器能够一行一行的进行编译。
2.编译请求的视图而不是在一个批次编译所有的视图
3.禁用请求超时,让我们可以长时间处于调试阶段
4.限制浏览器缓存的途径
这些都是在开发应用程序中非常有用的功能,但是这些功能会影响部署时的性能。解决的方法就是在部署时设置为:<compilation debug="true"  targetFramework="4.0">

 

准备一个Bin部署(Preparing for a Bin Deployment)

可以将程序部署到任何安装了ASP.NET4的IIS服务器上,即使是MVC 3的框架没有安装也可以。我们通过执行一个bin部署的操作来实现,MVC框架需要的程序集会包含在bin文件夹里面。具体操作如:在项目名称右键——>添加可部署的依赖项——>选中ASP.NET MVC——>确定,VS会自动添加一个名为  _bin_deployableAssemblies文件夹到项目里面,这里文件夹里面包含了MVC3和Razor需要的程序集。当我们编译程序时,这些程序集会拷贝到bin目录下,部署时就拷贝到服务器上。这意味着无论MVC3程序集是否在服务器的GAC里安装,我们的程序都会运行成功。

 

准备转换的Web.config(Preparing the Web.config  File for Transformation)

当我们部署一个应用时,通常会修改Web.config里面的部分配置节。VS提供了非常使用的功能让我们可以在不同的部署周期里生成不同版本的Web.config。在解决方案里面展开Web.config可以看到两个文件:Web.Debug.config和Web.Release.config,这两个文件对应Debug和Release两种配置。

View Code

上面的第二个转换是移除debug属性。这里我们实验一下,现在把上面的关于连接字符串的那部分注释去掉如下:

View Code

然后把解决方案配置改成Release模式,然后发布。这时打开Web.config可以看到连接字符串已经替换了,而且<compilation/>里面的debug也移除了。如下:


ps:到现在才知道Web.Release.config和Web.Debug.config是这么用的,之前都是部署了以后再去改连接字符串(太土了~~)。
下面会接着介绍应用到web.config的其他转换。

 

理解转换结构(Understanding the Transformation Structure)

转换文件基本结构跟Web.config相似。我们定义配置元素然后替换想转换的。转换文件的大致结构如下:
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings> 
    ...字符串转换部分... 
  </connectionStrings> 
  <system.web> 
    ...编译转换部分... 
  </system.web> 
</configuration>
对于每一个我们想要执行的转换,都定义了目标元素,必要的转换类型,以及任何转换需要的值。例如,要转换编译属性,那么就定义一个如下的转换:
<compilation xdt:Transform="RemoveAttributes(debug)" /> 
上面指明了我们想对Web.config里面的compilation节进行转换,使用的是RemoveAttributes转换并传入debug属性。
发布之前为<compilation debug="true" targetFramework="4.0">,发布之后为<compilation targetFramework="4.0">。下面的列表展示了支持的转换:

转换 描述
Insert 向Web.config插入元素
InsertBefore
InsertAfter
在指定的元素之前或之后插入
Remove 移除单个元素
RemoveAll 移除所有跟包含的元素同名的元素
RemoveAttributes 从包含的元素移除属性集合
SetAttributes 设置一个或多个属性的值
Replace 替换元素集合

 

 

 

 

 

 

 

 

 

下面对每一个转换进行介绍

 

插入配置元素

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings> 
    <add name="NewConnection" connectionString="MyConnectionString" xdt:Transform="Insert"/> 
  </connectionStrings> 
</configuration> 
复制代码

展示的结果为:

复制代码
<?xml version="1.0"?> 
<configuration> 
  <connectionStrings> 
    <add name="SportsStoreEntities"  
         connectionString="provider connection string= 
         &quot;Data Source=xTITAN\SQLEXPRESS;User ID=adam;Password=adam;&quot;"  
         providerName="System.Data.EntityClient" /> 
    <add name="NewConnection" connectionString="MyConnectionString"/> 
  </connectionStrings> 
  <system.web> 
    <compilation debug="true" targetFramework="4.0"> 
      <assemblies> 
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral" /> 
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral" /> 
      </assemblies> 
    </compilation> 
  </system.web> 
</configuration> 
复制代码

还可以使用InsertBefore和InsertAfter来控制插入的位置:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings> 
 
    <add name="NewConnection" connectionString="MyConnectionString"  
       xdt:Transform 
        ="InsertBefore(/configuration/connectionStrings/add[@name='SportsStoreEntities'])"/> 
 
    <add name="OtherConnection" connectionString="MyOtherConnectionString" 
       xdt:Transform 
        ="InsertAfter(/configuration/connectionStrings/add[@name='NewConnection'])"/> 
 
  </connectionStrings> 
</configuration> 
复制代码

InsertBefore和InsertAfter转换需要一个参数来指明插入的相对位置。参数使用了XPath语法,点这里了解XPath语法
展示执行结果:

复制代码
<?xml version="1.0"?> 
<configuration> 
  <connectionStrings> 
    <add name="NewConnection" connectionString="MyConnectionString"/> 
    <add name="OtherConnection" connectionString="MyOtherConnectionString"/> 
    <add name="SportsStoreEntities"  
         connectionString="provider connection string= 
         &quot;Data Source=TITAN\SQLEXPRESS;User ID=adam;Password=adam;&quot;"  
         providerName="System.Data.EntityClient" /> 
  </connectionStrings> 
  <system.web> 
    <compilation debug="true" targetFramework="4.0"> 
      <assemblies> 
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral" /> 
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral" /> 
      </assemblies> 
    </compilation> 
  </system.web> 
</configuration> 
复制代码

移除配置元素

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <system.web> 
    <compilation> 
      <assemblies> 
        <add xdt:Transform="Remove"/> 
      </assemblies> 
    </compilation> 
  </system.web>   
</configuration> 
复制代码

Remove转换会匹配集合区域的所有Add元素,当有一个或多个元素匹配时,仅仅第一个被移除。执行结果如下:

复制代码
<?xml version="1.0"?> 
<configuration> 
  <connectionStrings> 
      <add name="conn" connectionString="server=localhost;uid=root;pwd=***;database=sportsstore;"/>
  </connectionStrings> 
  <system.web> 
    <compilation debug="true" targetFramework="4.0"> 
      <assemblies> 
//移除的add
<!--<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral" />--> <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral" /> </assemblies> </compilation> </system.web> </configuration>
复制代码

要移除多个元素,可以使用RemoveAll转换。

 

设置/移除属性

可以使用SetAttributes和RemoveAttributes两个转换来操作Web.config里面的属性:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">  
  <connectionStrings> 
    <add name="SportStoreEntities" xdt:Transform="SetAttributes(connectionString)" 
       connectionString="MyNewConnection"/> 
  </connectionStrings> 
  <system.web> 
    <compilation xdt:Transform="RemoveAttributes(targetFramework)"  /> 
  </system.web>   
</configuration> 
复制代码

第一个转换会改变连接字符串的值,第二个转换会移除了targetFramework属性。结果如下:

View Code

替换元素

可以使用Replace转换来替换Web.config整个节,如:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings xdt:Transform="Replace"> 
    <add name="MyFirstConnection" connectionString="MyConnection1"/> 
    <add name="MySecondConnection" connectionString="MyConnection2"/> 
    <add name="MyThirdConnection" connectionString="MyConnection2"/> 
  </connectionStrings> 
</configuration>
复制代码

在上面的例子里,我们替换了包含了在connectionStrings元素里面的所有元素:结果如下

复制代码
<?xml version="1.0"?> 
<configuration> 
  <connectionStrings> 
    <add name="MyFirstConnection" connectionString="MyConnection1"/> 
    <add name="MySecondConnection" connectionString="MyConnection2"/> 
    <add name="MyThirdConnection" connectionString="MyConnection2"/> 
  </connectionStrings> 
  <system.web> 
    <compilation debug="true" targetFramework="4.0"> 
      <assemblies> 
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral" /> 
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral" /> 
      </assemblies> 
    </compilation> 
  </system.web> 
</configuration> 
复制代码

 

使用定位属性

Locator属性让我们能够更加明确我们所感兴趣的一个或多个元素。下面是一个没有使用Locator属性例子:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <system.web> 
    <compilation debug="true" targetFramework="4.0"> 
      <assemblies> 
        <add xdt:Transform="Remove"/> 
      </assemblies> 
    </compilation> 
  </system.web> 
</configuration> 
复制代码

这里会从assemblies区域移除add。正如我们前面提到的,Remove转换会移除找到的第一个元素,如果使用RemoveAll又会移除所有的元素。如果我们想移除匹配的元素中的一个时,可以使用Locator属性。如:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
 <system.web> 
   <compilation debug="true" targetFramework="4.0"> 
     <assemblies> 
      <add xdt:Transform="Remove" xdt:Locator="Condition(contains(@assembly,'Helpers'))" /> 
     </assemblies> 
   </compilation> 
 </system.web>   
</configuration> 
复制代码

这里指定Locator的值就限制了转换的元素是包含了Helpers的assembly属性。我们指定的表达式是联合了转换元素的路径,转换路径为:/configuration/compilation/assemblies/add并且有一个匹配assembly属性。Locator提供了三种模式供我们选择:

模式 用法 描述
Condition xdt:Locator="Condition(相对XPath表达式)" 联合相对的XPath表达式隐含转换元素的路径来限制元素的筛选
XPath xdt:Locator="XPath(绝对XPath表达式)" 应用绝对的XPath表达式来限制元素的筛选
Match xdt:Locator="Match(属性名)" 限制具有跟转换元素属性值匹配的元素的筛选

 

 

 

当我们使用Condition模式时,可以使用XPath运算符如contains,starts-with来创建更加复杂的搜索模式,还可以使用or和and运算符来创建复合表达式。如:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings> 
    <add xdt:Transform="SetAttributes(connectionString)" connectionString="MyConnection" 
         xdt:Locator= 
          "Condition(starts-with(@name, 'Sports') and contains(@providerName, 'Entity'))"/> 
  </connectionStrings> 
</configuration> 
复制代码

XPath模式允许我们指定一个绝对XPath表达式,如:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings> 
    <add xdt:Transform="SetAttributes(connectionString)" connectionString="MyConnection" 
         xdt:Locator= 
          "XPath(/configuration/connectionStrings/add[starts-with(@name, 'Sports') and  
              contains(@providerName, 'Entity')])"/> 
  </connectionStrings> 
</configuration> 
复制代码

如果我们的目标是匹配具体的属性值,那么我们能使用Match模式,如下:

复制代码
<?xml version="1.0"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
  <connectionStrings> 
    <add xdt:Transform="SetAttributes(connectionString)" connectionString="MyConnection" 
         xdt:Locator="Match(name, providerName)" 
         name="SportsStoreEntities" 
         providerName="System.Data.EntityClient"/>         
  </connectionStrings> 
</configuration> 
复制代码

Match模式需要一个或多个属性名作为参数,匹配Web.config中具有同样属性名和相同路径的元素。本例中,指定name和providerName,这意味着转换会对具有路径
/configuration/connectionStrings/add,并且具有一个值为SportsStoreEntities的name属性以及具有值为System.Data.EntityClient的providerName属性执行。

 

准备项目的数据库部署

另一个非常出色的部署功能是把数据库部署作为项目的一部分。我们可以选择从我们开发的数据库复制架构和/或数据到生产环境。
开始,设置项目为Release模式。接着在项目右键——>Properties——>Package/Publish Web并选中Include all databases configures in Package/Publish SQL如下:



然后转向Package/Publish SQL属性页,点击Import from  Web.config按钮,导入数据库连接字符串:


然后输入目标数据库连接字符串,然后选择部署什么,如下:

理解IIS基本原理
IIS是内置在Windows操作系统里的应用程序服务器,下面会介绍IIS的运行的背景。

理解Web站点
IIS能够同时寄宿多个独立的Web站点,对每一个站点必须指定根路径,这样IIS就会找到该文件下的无论是静态的还是动态的内容。为了将实际的请求导向一个实际的站点,IIS允许我们配置绑定,每一个绑定为IP地址,TCP端口映射所有的请求


理解虚拟目录
作为一个额外的配置级别,我们可以在一个web站点文件夹层级下的任何位置添加虚拟目录。每一个虚拟目录可以让IIS从一些其他的文件或网络路径获取内容并且就像这些内容是实际的在web站点的根文件夹下的虚拟目录呈现一样。如下:


每一个虚拟目录被标记为一个独立的应用,获取各自的配置和状态。相比它的父站点,它能够运行不同版本的ASP.NET.

 

理解应用程序池

IIS支持应用程序池的机制将运行在同一服务器的web应用程序隔离开,每一个程序启动一个独立的进程(包括具有不同的进程标识,最大内存使用,最大CPU使用,处理回收计划等等)。每一个站点被指派到应用程序池中的一个,如果其中一个应用崩溃了,其他的应用不会受到影响。由于同一台服务器可能寄宿多个站点,这就需要分派请求到正确的站点:我们可以绑定站点到一个或多个由下面三个部分构成的组合:
1.端口号(大多数都是80)  2.Hostname   3.IP地址

 后续的对IIS的操作均跟之前在Webform里面的操作一样,安装部署Webform的方式就行了。所以后面的笔记略去,如果大家在实际的操作有什么问题,欢迎留言讨论!

今天特意看了第一篇笔记的时间2011-11-30,整个笔记到今天为止近7个月的时间,现在告于段落。感谢园友的支持,谢谢!接下来我打算学习nopcommerce这个开源项目来加深MVC的学习。希望已经接触了该开源项目的同学能够提供资源或学习建议,谢谢!

本文转自Rt-张雪飞博客园博客,原文链接http://www.cnblogs.com/mszhangxuefei/archive/2012/06/20/mvcnotes_35.html如需转载请自行联系原作者


张雪飞

相关文章
|
1月前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
2月前
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
82 1
|
2月前
|
监控 安全 API
Docker + .NET API:简化部署和扩展
Docker + .NET API:简化部署和扩展
39 0
|
2月前
|
监控 安全 API
最完美的扩展Docker + .NET API:简化部署和扩展
最完美的扩展Docker + .NET API:简化部署和扩展
87 0
|
3月前
|
SQL 关系型数据库 数据库
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
|
4月前
|
开发框架 监控 安全
.NET 应用程序安全背后究竟隐藏着多少秘密?从编码到部署全揭秘!
【8月更文挑战第28天】在数字化时代,.NET 应用程序的安全至关重要。从编码阶段到部署,需全面防护以保障系统稳定与用户数据安全。开发者应遵循安全编码规范,实施输入验证、权限管理和加密敏感信息等措施,并利用安全测试发现潜在漏洞。此外,部署时还需选择安全的服务器环境,配置 HTTPS 并实时监控应用状态,确保全方位防护。
59 3
|
4月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
85 0
|
4月前
|
开发框架 .NET Docker
【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
|
4月前
|
开发框架 .NET API
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
198 3
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
54 0