MVC3的新特性介绍

MVC3 新特性

摘要

MVC经过其1.0和2.0版本的发展,现在已经到了3.0的领军时代,随着技术的不断改进,MVC也越来越成熟。使开发也变得简洁人性化艺术化。

前言

ASP.NET MVC3 在 ASP.NET MVC 1 和 2 的基础上,增加了大量的特性,使得代码更加简化,并且可以深度扩展。这篇文章提供包含在此次发布中的许多新特性的说明,分为以下部分:

  • Razor 视图引擎
  • 支持多视图引擎
  • Controller 改进
  • JavaScript 和 Ajax
  • Model 验证的改进
  • 依赖注入 Dependency Injection 的改进
  • 其他新特性

 

Razor 视图引擎

ASP.NET MVC3 带来了一种新的名为 Razor 的视图引擎,提供了下列优点:

  • Razor 的语法简单且清晰,只需要最小化的输入
  • Razor 容易学习,语法类似于 C# 和 VB
  • Visual Studio 对于 Razor 提供了智能提示和语法着色
  • Razor 视图不需要允许程序或者启动 Web 服务器就可以进行测试

Razor 现在提供了一些新的特征:

  • @model 用来指定传到视图的 Model 类型
  • @*  * 注释语法
  • 对于整个站点可以一次性设定默认项目,例如布局。
  • Html.Raw 方法提供了没有进行 HTML 编码的输出
  • 支持在多个视图之间共享代码 ( _viewstart.cshtml 或者 _viewstart.vbhtml )->View的基类

Razor 还包含新的  HTML Helper,例如:

  • Chart. 生成图表
  • WebGrid, 生成数据表格,支持完整的分页和排序
  • Crypto,使用 Hash 算法来创建 Hash 和加盐的口令
  • WebImage, 生成图片(http://www.cnblogs.com/facingwaller/archive/2010/12/07/how_to_use_webimage_in_razor.html)
  • WebMail, 发送电子邮件(http://www.cnblogs.com/facingwaller/archive/2010/12/07/how_to_send_mail_in_razor.html)

一、示例代码:

1.MVC3MVC2代码比较:

View:

MVC3

MVC2

Index.cshtml

Index.aspx

@{

    ViewBag.Title = "Home Page";

}

 

<h2>@ViewBag.Message</h2>

 

<p>

    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.

</p>

 

 

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">

    Home Page

</asp:Content>

 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%: ViewData["Message"] %></h2>

    <p>

        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.

    </p>

</asp:Content>

 

Foreach循环

<h2>Products</h2>

<ul>

@foreach (var p in products) {

<li>@p.ProductionName</li>

}

</ul>

 

<h2>Products</h2>

    <ul>

    <%foreach (dynamic p in Model)

      {%>

    <li><%:p.ProductName%></li>

    <%} %>

    </ul>

 

 

 

 

Controller:

MVC3

MVC2

public ActionResult Index()

        {

            ViewBag.Message = "Welcome to ASP.NET MVC!";

            //ViewModel

            return View();

        }

 

public ActionResult Index()

        {

            ViewData["Message"] = "Welcome to ASP.NET MVC!";

 

            return View();

        }

 

 

关于 Razor 更多的资料,可以参考下面的资源:

  • Scott Guthrie's blog post introducing Razor
  • Scott Guthrie's blog post introducing the @model keyword
  • Scott Guthrie's blog post introducing Razor layouts
  • Razor API Quick Reference
  • MVC 3 Release Notes

2.Razor的新关键字@model

@model指示符提供了一个更加好用的功能,使我们在View中引用强类型数据模型的方式更加干净整洁。

我们来看一个超级简单的脚本例子,我们要实现一个或多个产品的URL,用来列出数据库中产品分类:

 

以下是一个简单的ProductsController,实现了产品列表的URL。可以遍历数据库中的产品类别,并传递到View文件中生成一个适当的HTML文件,响应浏览器的请求。

 

如果我们已经在ASP.NET MVC 3预览第一版中使用过Razor,如果我们想要使Index.cshtml视图文件中绑定到System.Web.Mvc.WebViewPage<TModel>这个类,则需要在头部加上@inherits声明。我们是想指明View文件和传递过来的强类型关联起来。

 

This works (and is still supported with ASP.NET MVC 3) - but is a little verbose.

这样是可行的(并且仍被ASP.NET MVC 3所支持)--但这有点冗长了。

我们已经在ASP.NET MVC 3测试版中加入了@model指示符,这样可以更干净简洁地指明你在View文件中想引用一个强类型模型的类。现在,你只需要在文件首部写上"@model 强类型模型类",也就不用再写@inherits声明或指定View所基于其上模型的类:

 

上面的语法和之前的语法在概念上并没有什么两样(除了少得多的代码)。这样更有利于编写和阅读代码。

 

参考:http://www.cnblogs.com/xiaxiazl/archive/2012/04/14/2447081.html

http://weblogs.asp.net/scottgu/archive/2010/10/19/asp-net-mvc-3-new-model-directive-support-in-razor.aspx

 

3、Razor基本语法

Razor关键字

意义

示例

@

代表开始一个Razor代码块,Razor会自动匹配代码中的花括号

@if(p.Active){<li>@p.Name</li>}

@{code}

标识一个Razor多行代码块,相当于<% CODE %>

1.赋值定义操作

@{

    ViewBag.Title = "Home Page";

}

2.使用逻辑处理

@{

    if (xx)

    {

    //do something

    }

    else

    {

    //do anything

    }

}

3.在@{... }内部使用html标记

@{

    <p>text</P>

    <div>div1</div>

}

4. 在@{...}内部输出文本
利用@:进行单行输出

@{

    @:This is some text

    @:This is text too

    @:@i 也可输出变量

}

5. 利用<text />进行多行输出

@{

    <text>

        tomorrow is good

        some girl is nice

    </text>

}

 

6. 在@{...}内部使用注释

@{

    //单行注释

    var i = 10;

    //defg

}

 

    @* 多行注释 *@

    @*

        多行注释

        多行注释

    *@

 

 

@{

    @*

        多行注释

        多行注释

    *@

    var i = 10;  @* asdfasf *@

}

 

<!-- 同时也可以使用C#默认的/* ... */ -->

 

@{

    /*

        多行注释

    */

}

 若在@{ ... }内部使用<!-- -->注释,则会输出到页面之中,如果在<!-- -->内部使用@变量,则会被处理
@{

<!-- time now: @DateTime.Now.ToString() -->
}
输出: <!-- time now: 4/9/2011 12:01 -->

 

 

@model

指定ViewModel

@model MVCProject.UI.Models.ProductModel

@section SectionName{}

定义局部布局,类似于Master的ContentPlace,可以在布局模板中使用@RenderSection呈现

@section SubMenu{
    Hello This is a section implement in About View.
 }

更多参考:http://www.cnblogs.com/dragon_mail/archive/2011/06/30/2094884.html

@:

指定当前按Content处理,但是可以有内嵌的Razor代码

@{

    @:This is some text

    @:This is text too

    @:@i 也可输出变量

}

<text>...</text>

功能同@:,区别是还可以指定多行Content

<text>

        tomorrow is good

        some girl is nice

    </text>

@*....*@

注释

见@{}

@(expression)

用于辅助Razor识别表达式

@for (int i = 10; i < 11; i++)

{

    @:@i

}

 

Razor语法之类型转换

AsInt(), IsInt()
AsBool(),IsBool()
AsFloat(),IsFloat()
AsDecimal(),IsDecimal()
AsDateTime(),IsDateTime()
ToString()
例子:

@{

    var i = “10”;

}

 

<p> i = @i.AsInt() </p> <!-- 输出 i = 10 -->

 

Razor语法之使用循环

<!--方式1-->

@for (int i = 10; i < 11; i++)

{

    @:@i

}

<!--方式2-->

@{

    for (int i = 10; i < 11; i++)

    {

        //do something

    }

}

 

<!--while同理-->

 

Razor 还包含新的  HTML Helper

ASP.NET3为我们带来了很多新特性,其中ChartHelper也是相当给力。比如我们要生成一张这样的图表:

 

我们需要在controller中这样写(这里不考虑通过ViewModel在页面上通过Chart生成图表的方式):

public ActionResult Chart2() {

    var chart = new Chart(width: 500, height: 300, theme: ChartTheme.Blue)

        .AddSeries(

            chartType: "bar",

            legend: "Rainfall",

            xValue: new[] { "南京", "武汉", "上海", "苏州", "沈阳" },

            yValues: new[] { "95", "80", "70", "72", "92" })

        .AddTitle("分公司年末预测率汇总")

        .SetXAxis(title: "分公司")

        .SetYAxis(title: "预测率(%)");

    chart.Write();

    return null;

}

然后页面上用一个img标签载入action生成的图片

<img src="/Home/Chart2" alt="测试图表2" />

 

但是那个return null是不是有点过分的ugly了?为此我们可以简单编写一个ChartResult:

public class ChartResult : ActionResult {

    private readonly Chart _chart;

    private readonly string _format;

 

    public ChartResult(Chart chart, string format = "png") {

        if (chart == null)

            throw new ArgumentNullException("chart");

 

        _chart = chart;

        _format = format;

 

        if (string.IsNullOrEmpty(_format))

            _format = "png";

    }

 

    public Chart Chart {

        get { return _chart; }

    }

 

    public string Format {

        get { return _format; }

    }

 

    public override void ExecuteResult(ControllerContext context) {

        _chart.Write(_format);

    }

}

(注意这里用到了可选参数,如果您还在用.NET3.5,请自行调整)

 

最终controller中的代码:

public ActionResult Chart2() {

    var chart = new Chart(width: 500, height: 300, theme: ChartTheme.Blue)

        .AddSeries(

            chartType: "bar",

            legend: "Rainfall",

            xValue: new[] { "南京", "武汉", "上海", "苏州", "沈阳" },

            yValues: new[] { "95", "80", "70", "72", "92" })

        .AddTitle("分公司年末预测率汇总")

        .SetXAxis(title: "分公司")

        .SetYAxis(title: "预测率(%)");

   

return new ChartResult(chart);

 

}

其他图:

 

 

 

  • WebGrid, 生成数据表格,支持完整的分页和排序

 

aspx

 

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<WebGridAspx.Models.Products>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    产品列表
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script  type="text/javascript">
    function deleteRecord(a, b) {
        alert("删除:"+b);
    }
</script>
 <h2>产品列表</h2> 
 <div id="grid">
 <% var grid = new WebGrid(source: Model, defaultSort: "ProductName", rowsPerPage: 5); %>
 <%=grid.GetHtml(
     tableStyle: "grid",
     headerStyle: "head",
     alternatingRowStyle: "alt",
     columns: grid.Columns(
               grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.ProductID })),
               grid.Column(format: (item) => Html.ActionLink("Delete", "Delete", null, new { onclick = string.Format("deleteRecord('Employee', '{0}')", item.ProductID), @class = "Delete", href = "JavaScript:void(0)" })),
               grid.Column("ProductName","产品名称"),
               grid.Column("QuantityPerUnit","每单位数量"),
               grid.Column("UnitPrice","单价"),
               grid.Column("UnitsInStock", "库存单位"),
               grid.Column("UnitsOnOrder","订单单位"),
               grid.Column("ReorderLevel","重新排序级别"),
               grid.Column("Discontinued","已停产")
     )
     )

 
   %>
 </div>


</asp:Content>

 

Razor

 

代码

 @model List<WebGridRazor.Models.Products>
 @{
  View.Title = "产品列表";
 }

 <p>
 <h2>产品列表</h2> 
 <div id="grid">
  @{ 
  
  var grid = new WebGrid(source: Model,
  defaultSort: "ProductName", 
  rowsPerPage: 3);
 }
  @grid.GetHtml(
     tableStyle: "grid",
     headerStyle: "head",
     alternatingRowStyle: "alt",
     columns: grid.Columns(
          grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.ProductID })),
          grid.Column(format: (item) => Html.ActionLink("Delete", "Delete", null, new { onclick = string.Format("deleteRecord('Product', '{0}')", item.ProductID), @class = "Delete", href = "JavaScript:void(0)" })), 
          grid.Column("ProductName","产品名称"),
          grid.Column("QuantityPerUnit","每单位数量"),
          grid.Column("UnitPrice","单价"),
          grid.Column("UnitsInStock", "库存单位"),
          grid.Column("UnitsOnOrder","订单单位"),
          grid.Column("ReorderLevel","重新排序级别"),
          grid.Column("Discontinued","已停产")
     )
     )
 </div>
 </p>

 

支持多视图引擎

 在 ASP.NET MVC3 中,增加视图的对话框中允许你选择你希望的视图引擎,在新建项目对话框中,你可以指定项目默认的视图引擎,可以选择 WebForm,Razor,或者开源的视图引擎,例如:Spark, NHaml, 或者 NDjango.

选择视图引擎:

 

 

控制器的改进

 全局的 Action 过滤器

有的时候你希望能够在在一个 Action 方法执行之前或者执行之后执行一些处理逻辑,在 ASP.NET MVC2 中,提供了 Action 过滤器,允许对特定控制器的 Action 方法进行处理,实际上,有时候你希望对所有的 Action 都进行类似的处理,MVC3 允许你将过滤器加入到 GlobalFilters 集合中来创建全局的过滤器,

先写好Filter:

 

再将写好的Filter注册到全局Global.asax中:

 

最后直接运用在Controller中:

 

附:一些常用于Action中的系统Filter:

AcceptVerbs

规定页面的访问形式,如

        [AcceptVerbs(HttpVerbs.Post)]
         public ActionResult Example(){
             return View();
         }

ActionName

规定Action的名称。

应用场景:如果不想用方法名做为Action名,或Action名为关键字的话,如

       [ActionName("class")]
         public ActionResult Example(){
             return View();
         }

 

NonAction

当前方法仅是普通方法不解析为Action

OutputCache

为Action添加缓存

        [OutputCache(Duration = 60, VaryByParam = "*")]
        public ActionResult Example()
        {
            return View();
        }

 

ValidateInput

该Action可以接受Html等危险代码(ASP.NET MVC在aspx中设置<%@ Page 的属性无法完成等同任务。)

        [ValidateInput(false)]
        public ActionResult Example()
        {
            return View();
        }

 

ValidateAntiForgeryTokenAttribute

用于验证服务器篡改。

        [ValidateAntiForgeryToken]
        public ActionResult Example()
        {
            return View();
        }

 

 

详细的介绍,参考下列资源:

  • Scott Guthrie's blog on the MVC 3 Preview
  • Filtering in ASP.NET MVC
  • http://www.cnblogs.com/chsword/archive/2009/03/12/zd_mvc6.html

新的 ViewBag 属性

MVC2 中的控制器支持 ViewData 属性,允许通过后绑定的字典将数据传送给视图模板,在 MVC3 中,你可以通过 ViewBag 来更加简单的完成。例如,对于 ViewData["Message"] = "text",你可以通过 ViewBag.Message = "text" 来完成。你不需要通过类来定义任何强类型的属性,因为这是动态属性,在内部,ViewBag 属性以名-值对的形式保存在 ViewData 字典中。注意,在许多预发布版本中,这个属性被称为 ViewModel。

新的 ActionResult 类型

下面的 ActionResult 类型在 MVC3 中是新增的或者被扩展的。

  • . 向客户端返回 404 HTTP 状态. HttpNotFoundResult
  • . 基于一个布尔型的参数,返回一个临时的重定向 (HTTP 302 status code) 或者持久的重定向 (HTTP 301 status code),  结合这个改进,,  提供了三个方法来支持持久的重定向: , , 和 . 这些方法返回一个   属性为真的 对象实例。RedirectResultControllerRedirectPermanentRedirectToRoutePermanentRedirectToActionPermanentPermanentRedirectResult
  • . 返回用户指定的 HTTP 状态码。 HttpStatusCodeResult

JavaScript  Ajax 改进

 默认情况下,在 MVC3 中,Ajax 和验证使用不引人注目的 unobtrusive  的 JavaScript 方式。unobtrusive  不会在 HTML 中插入行内的 JavaScript ,这使得 HTML 更加精简和更少干扰,也使得更加容易被替换和定制 JavaScript 库,在 MVC3 中,验证助手默认使用 jQuery.Validate 插件完成,如果你希望使用 MVC2 的行为,你可以在 web.config 中通过配置来关闭 unobtrusive ,

 

或者用代码手动开启/关闭:HtmlHelper.UnobtrusiveJavaScriptEnabled = true/false;

更多的信息参考下列资源:

  • Basic introduction to unobtrusive JavaScript on the Wikipedia site
  • Brad Wilson's Unobtrusive JavaScript Post
  • Brad Wilson's Unobtrusive JavaScript Validation Post
  • (tutorial on the ASP.NET site) Creating a MVC 3 Application with Razor and Unobtrusive JavaScript
  • MVC 3 Release Notes

默认启用了客户端验证

 在早先版本的 MVC 中,你需要在视图中显式调用 Html.EnableClientValidation 方法来启用客户端验证。在 MVC3 中,已经不再需要了,因为默认就会启用客户端验证。可以在 web.config 中关闭。

为了使得客户端验证工作,你仍然需要在网站中加入对 jQuery 和 jQuery.Validation 库的引用,你可以在自己的网站中提供,或者使用 Microsoft 或者 Google 的 CDN 服务器。

远程验证

ASP.NET 3 通过一个新的标签 RemoteAttribute 对 jQuery Validation 插件的远程验证提供支持。这允许客户端的验证库自动调用一个你定义在服务器上的自定义的方法来完成只能在服务器上完成的验证逻辑。

在下面的例子中,Remote 标签指定了通过一个定义在 UsersController 中名为 UserNameAvailable 的方法来验证用户名字段。

public class User  

    [Remote("UserNameAvailable", "Users")] 
    public string UserName { get; set; } 
}

 

下面的代码定义在控制器中

 

public class UsersController  
{  
    public bool UserNameAvailable(string username)  
    {  
        if(MyRepository.UserNameExists(username))  
        {  
            return "false";  
        }  
        return "true";  
    }  
}

 

 

关于 Remote 属性的更多资源,参考  How to: Implement Remote Validation in ASP.NET MVC

JSON 绑定支持

ASP.NET MVC3 包含内置的 JSON 绑定支持,允许 Action 方法接收 JSON 编码的数据并且模型化为 Action 的参数。这个能力经常被用于客户端的模板和数据绑定中。客户端模板允许你通过客户端的模板来格式化和显示一个或者多个数据,MVC3 允许你简单的连接客户端模板和服务器端的 Action 方法,通过 JSON 来发送和接收数据,

示例:

ASP.NET MVC 3 中内置了对 JSON 的绑定支持,使得接收从客户端传递过来的 JSON 格式的数据变得非常简单。本篇还是以 Android 博客项目中的留言小功能来简单的说明一下具体的使用方法。先看看 Razor 视图引擎下的 HTML代码,这块主要用来显示留言的数据列表:

<div>

    <script id="userTemplate" type="text/html">

    <div><a href="${Website}">${UserName}</a> Says: ${Content}</div>

    </script>

    <div id="Contact"></div>

    <input type="button" id="create" value="Create" />

</div>

当我们点击 Create 按钮时提交留言(这里为了简单,留言内容固定了),执行 jQuery Ajax 传递 JSON 格式数据,如下:

$("#create").click(function () {

    var contact = {

        UserName: "I love jQuery",

        Website: "http://www.google.com",

        Content: "Nice to meet you."

    };

 

    $.ajax({

        url: "/Contact",

        type: "POST",

        data: contact,

        dataType: "json",

        success: function (req) {

            $("#userTemplate").render(req).appendTo("#Contact");

        }

    });

});

如果你是纯 ASP.NET 开发者,没有接触过 jQuery ,那么我要强烈的建议你赶快学习 jQuery ,jQuery 在 ASP.NET MVC 3 中起着非常重要的作用,它会越来越流行。现在,你可以参考下jQuery学习大总结(五)jQuery Ajax。这样将留言内容以JSON 结构通过 POST 方式向后台提交,ASP.NET MVC 3 Controller 中接收代码如下:

[HttpPost]

public ActionResult Index(Contact contact)

{

    if (ModelState.IsValid)

    {

        android.Contact.AddObject(contact);

        android.SaveChanges();

    }

    var contacts = from c in android.Contact

                    where c.IsValid == 1

                    select c;

    return Json(contacts);

}

 

更多的信息参考:

Scott Guthrie's MVC 3 Preview blog post.

ASP.NET MVC3 技术(五) JSON 数据的传递

http://www.jquery001.com/pass-json-data-in-asp.net-mvc3.html

 

Model 验证的改进

DataAnnotations 元数据标签

ASP.NET MVC3 支持 DataAnnotations 元数据标签,例如:DisplayAttribute。

ValidationAttribute 

在 .NET Framework4 中被改进 的ValidationAttribute 类支持新的 IsValid 重载,提供关于当前验证上下文的更多信息,例如什么对象被验证了。这允许你基于 Model 的其他属性来验证当前值,例如,新的 CompareAttribute 就允许你比较 Model 的两个属性的值,在下面的例子中,ComparePassword 属性必须匹配 Password 字段来同通过验证。

 

public class User 
{  
    [Required] 
    public string Password { get; set; }  
    [Required, Compare("Password")]  
    public string ComparePassword { get; set; }  
}

 

 

验证接口

IValidatableObject 接口允许执行 Model 水平的验证,并且允许你提供整个模型状态的验证错误信息,或者基于 Model 的两个属性。当 Model 绑定的时候,MVC3 从 IValidatableObject 接收错误信息,在视图中使用内建的 HTML 助手时,将会自动标识或者高亮受影响的字段。

IClientValidatable 接口允许 ASP.NET MVC 在运行时发现支持的客户端验证器,这个接口被用来支持集成不同的验证框架。

更加关于验证接口的内容,参考 Scott Guthrie's MVC 3 Preview blog post 中 Model Validation Improvements 一节。

依赖注入Dependency Injection 的改进

ASP.NET MVC3 提供了更好的 DI 和 IoC 支持,在下面的地方支持 DI:

  • 控制器 (registering and injecting controller factories, injecting controllers).
  • 视图 (registering and injecting view engines, injecting dependencies into view pages).
  • Action 过滤器 (locating and injecting filters).
  • Model 绑定器 (registering and injecting).
  • Model 验证提供器 (registering and injecting).
  • Model 元数据提供器 (registering and injecting).
  • Value 提供器 (registering and injecting).

MVC3 支持  Common Service Locator 库和任何支持这个库的 IServiceLocator 接口的 DI 容器。也支持新的容易集成到 DI 框架的 IDependencyResolver  接口。

依赖注入:英文是Dependency Injection。有时候也称为反转控制(Ioc)吧。不管名词怎么讲,它的大致意思是,让我们的应用程序所依赖的一些外部服务,可以根据需要动态注入,而不是预先在应用程序中明确地约束。这种思想,在当前的软件开发领域,为了保证架构的灵活性,应该还是很有意义的。

在MVC这个框架中,为依赖注入的设计提供了先天的支持。结合一些我们熟知的DI组件,例如NInject,我们可以较为容易地实现上述提到的功能。

 

场景介绍

我们的应用程序,需要支持各种不同的数据源,而且我们希望日后可以很容易地切换,不会因为数据源的变化而导致对Contoller或者Model,或者View做修改。

 

本文完整源代码,请通过这里下载 MvcApplicationDISample.rar

 

演练步骤

第一步:准备一个MVC项目(选择空白模板)

 

第二步:准备一个业务实体类型

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

namespace MvcApplicationDISample.Models

{

    public class Employee

    {

        public int ID { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

    }

}

第三步:准备一个数据访问的接口定义

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using MvcApplicationDISample.Models;

 

namespace MvcApplicationDISample.Services

{

    public interface IDataService

    {

        Employee[] GetEmployee();

    }

}

第四步:创建一个HomeController

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using MvcApplicationDISample.Services;

using MvcApplicationDISample.Models;

 

 

namespace MvcApplicationDISample.Controllers

{

    public class HomeController : Controller

    {

 

        IDataService DataService;

        public HomeController(IDataService service)

        {

            DataService = service;

        }

 

        //

        // GET: /Home/

 

        public ActionResult Index()

        {

            var data = DataService.GetEmployee();

            return View(data);

        }

 

    }

}

注意,这里需要为HomeController添加一个特殊的构造函数,传入IDataService这个接口。通常,所有的DI组件都是通过这样的方式注入的。

在设计HomeController的时候,我们不需要关心到底日后会用具体的哪种DataService,我们只是要求要传入一个IDataService的具体实现就可以了,这就是DI的本质了。

 

到这里为止,我们该做的准备工作基本就绪了。下面来看看如何结合DI组件来实现我们的需求

 

第五步:引入NInject组件

这是我比较喜欢的一个DI组件。它还针对MVC3专门有一个扩展

 

 

 

添加这个组件之后,除了自动添加了很多引用之外,还有一个特殊的文件App_Start\NinjectMVC3.cs

 

 

[assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplicationDISample.App_Start.NinjectMVC3), "Start")]

[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplicationDISample.App_Start.NinjectMVC3), "Stop")]

 

namespace MvcApplicationDISample.App_Start

{

    using System.Reflection;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;

    using Ninject.Web.Mvc;

 

    public static class NinjectMVC3

    {

        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

 

        /// <summary>

        /// Starts the application

        /// </summary>

        public static void Start()

        {

            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));

            DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));

            bootstrapper.Initialize(CreateKernel);

        }

       

        /// <summary>

        /// Stops the application.

        /// </summary>

        public static void Stop()

        {

            bootstrapper.ShutDown();

        }

       

        /// <summary>

        /// Creates the kernel that will manage your application.

        /// </summary>

        /// <returns>The created kernel.</returns>

        private static IKernel CreateKernel()

        {

            var kernel = new StandardKernel();

            RegisterServices(kernel);

            return kernel;

        }

 

        /// <summary>

        /// Load your modules or register your services here!

        /// </summary>

        /// <param name="kernel">The kernel.</param>

        private static void RegisterServices(IKernel kernel)

        {

        }       

    }

}

这个类型很有意思,WebActivator.PreApplicationStartMethod这个方法其实是注册了一个在MVC程序启动之前运行的方法。这些代码大家应该能看懂,它在CreateKernel中,添加一个新的Kernel(用来做注入的容器)。

 

第六步:创建一个IDataService的具体实现

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using MvcApplicationDISample.Models;

 

namespace MvcApplicationDISample.Services

{

    public class SampleDataService:IDataService

    {

        #region IDataService Members

 

        public Employee[] GetEmployee()

        {

            return new[]{

                new Employee(){ID=1,FirstName="ares",LastName="chen"}};

        }

 

        #endregion

    }

}

作为举例,我们这里用了一个硬编码的方式实现了该服务。

第七步:实现注入

回到App_Start\NinjectMVC3.cs这个文件,修改RegisterServices方法如下

       /// <summary>

        /// Load your modules or register your services here!

        /// </summary>

        /// <param name="kernel">The kernel.</param>

        private static void RegisterServices(IKernel kernel)

        {

            kernel.Bind<Services.IDataService>().To<Services.SampleDataService>();

        }     

第八步:测试Controller的功能

 

我们可以看到,数据已经展现出来了。这说明,HomeController中的Index方法,确实调用了我们后期插入的这个SampleDataService。而通过下图,则可以更加清楚看到这一点

 

到这里为止,我们就结合Ninject组件实现了一个简单的依赖注入的实例。Ninject 针对MVC 3有这么一个特殊的文件,可以极大地方便我们的编程。但即便没有这个文件,我们也可以通过另外一些方法来实现需求。

下面介绍两种比较传统的,通过扩展MVC组件实现的方式

第一种:实现自定义ControllerFactory

我们都知道,Controller其实都是由ControllerFactory来生成的,那么,为了给所有新创建从Controller都自动注入我们的服务,那么就可以从ControllerFactory这个地方动动脑筋了。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using Ninject;

using MvcApplicationDISample.Services;

 

namespace MvcApplicationDISample.Extensions

{

    public class InjectControllerFactory:DefaultControllerFactory

    {

 

        private IKernel kernel;

        public InjectControllerFactory()

        {

            kernel = new StandardKernel();

            kernel.Bind<IDataService>().To<SampleDataService>();

        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)

        {

            return (IController)kernel.Get(controllerType);

        }

    }

}

要使用这个自定义的 ControllerFactory,我们需要修改Global.ascx文件中的Application_Start方法,添加下面的粗体部分代码

        protected void Application_Start()

        {

            AreaRegistration.RegisterAllAreas();

 

            RegisterGlobalFilters(GlobalFilters.Filters);

            RegisterRoutes(RouteTable.Routes);

 

           ControllerBuilder.Current.SetControllerFactory(new Extensions.InjectControllerFactory());

        }

 

这样做好之后,我们可以测试HomeController中的Index这个Action,我们发现它还是能正常工作。

 

 

 

第二种:实现自定义的DependencyResolver

顾名思义,这就是MVC框架里面专门来处理所谓的依赖项的处理器。可以说这是MVC专门为DI准备的一个后门。下面是我写好的一个例子

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using Ninject;

using MvcApplicationDISample.Services;

 

namespace MvcApplicationDISample.Extensions

{

    public class InjectDependencyResolver:IDependencyResolver

    {

        private IKernel kernel;

 

        public InjectDependencyResolver()

        {

            kernel = new StandardKernel();

            kernel.Bind<IDataService>().To<SampleDataService>();

        }

 

        #region IDependencyResolver Members

 

        public object GetService(Type serviceType)

        {

            return kernel.TryGet(serviceType);

        }

 

        public IEnumerable<object> GetServices(Type serviceType)

        {

            return kernel.GetAll(serviceType);

        }

 

        #endregion

    }

}

 

那么,如何使用这个自定义的处理器呢?

很简单,我们仍然是修改Global.asax文件中的Application_Start方法

        protected void Application_Start()

        {

            AreaRegistration.RegisterAllAreas();

 

            RegisterGlobalFilters(GlobalFilters.Filters);

            RegisterRoutes(RouteTable.Routes);

 

            //ControllerBuilder.Current.SetControllerFactory(new Extensions.InjectControllerFactory());

 

            DependencyResolver.SetResolver(new Extensions.InjectDependencyResolver());

        }



请注意,之前那个设置ControllerFactory的代码,我们可以注释掉了

这个解决方案的最终效果和之前是一样的。

 

 

 

更多关于 DI 的信息,参考:

  • Brad Wilson's series of blog posts on Service Location
  • MVC 3 Release Notes
  • http://www.csharpwin.com/dotnetspace/13049r3161.shtml

 

其他新特性

 NuGet 集成

ASP.NET MVC3 自动安装和启用 NuGet ,NUGet 是免费开源的一个包管理器,使得在你的项目中容易发现,安装,和使用 .NET 库。它可以和所有的 Visual Studio 项目类型一起工作,包括 ASP.NET WebForm 和 MVC。

NuGet 允许开发者维护开源项目,例如,像 Moq 项目,NHibernate 等等,可以注册它们到一个在线的网站中。

更多信息参考:

NuGet documentation on the CodePlex site.

http://www.cnblogs.com/lzrabbit/archive/2012/05/01/2477873.html

部分页的输出缓存

ASP.NET MVC 从版本1 开始支持整页缓存,MVC3 还提供了部分页缓存。这可以允许你容易地缓存输出的一个区域或者片断,更多地内容参考  Scott Guthrie's blog post on the MVC 3 release candidate  中 Partial Page Output Caching 段落,还有 MVC 3 Release Notes 中 Child Action Output Caching 段落。

在请求验证中的粒度控制

ASP.NET MVC 内建了请求验证机制来自动帮助处理类似跨站攻击和 HTML 注入等等。实际上,有时你希望能够显式关闭请求的验证,例如你希望允许用户提交 HTML 内容,例如在内容管理系统中,现在你可以通过增加 AllowHtml 标签到 Model 或者视图的 Model 来支持在绑定的时候基于一个属性关闭请求验证。更多地资料参考:

  •   中 一节. Scott Guthrie's blog post on the MVC 3 release candidateUnobtrusive JavaScript and Validation
  • MVC 3 Release Notes

可扩展的新建项目对话框

在 MVC3 中,你可以增加项目模板,视图引擎,单元测试项目框架到新建项目对话框中。

脚手架的改进

MVC3 中的脚手架对于主键提供了更好的支持,例如,脚手架的模板不会将主键加入的编辑表单中了。

默认情况下,创建和编辑的脚手架现在使用 Html.EditorFor 助手来替代 Html.TextBoxFor 助手,这个改进在增加视图对话框生成一个视图的时候,支持模型中的元数据标签。

对于 Html.LabelFor  Html.LabelForModel 的新重载

对于 LabelFor 和 LabelForModel 增加了新的方法重载,允许指定或者重写 Label 文本。

 Session 的控制器支持

MVC3 中可以指定控制器是否使用 Session 状态,进而,Session 是否是读写还是只读。

新的 AdditionalMetadataAttribute 

可以通过 AdditionalMetadataAttribute 标签对 Model 的一个属性访问 ModelMetadata.AdditionalValues 字典,例如,如果模型的某个属性仅仅支持管理员显示,你可以如下设置:

public class ProductViewModel  

    [AdditionalMetadata("AdminOnly", true)] 
    public string RefundCode {get; set;} 
}

 

当使用产品的 Model 来生成的时候,这个元数据将被任何显示或者编辑模板使用,这允许你来解释元数据信息。

 

转载于:https://www.cnblogs.com/douqiumiao/archive/2013/02/01/2889330.html

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. component.html 404 angular

    component.html 404 angular 问题 项目启动后&#xff0c;浏览器报错404&#xff1a;can’t load resources / can’t find component 或者 无报错&#xff0c;加载页面一直转圈 解决 包引入的路径写成这样是不行的&#xff0c;注意最后的斜杠 import { foobar } from ang…...

    2024/3/16 0:04:04
  2. 割双眼皮 吃什么好

    ...

    2024/3/16 0:04:04
  3. Java NIO框架Netty教程(一) Hello Netty(转)

    2019独角兽企业重金招聘Python工程师标准>>> 先啰嗦两句,如果你还不知道Netty是做什么的能做什么。那可以先简单的搜索了解一下。我只能说Netty是一个NIO的框架,可以用于开发分布式的Java程序。具体能做什么,各位可以尽量发挥想象。技术,是服务于人而不是局限住…...

    2024/3/16 0:04:02
  4. 割双眼皮 疤克

    ...

    2024/3/16 0:04:01
  5. angular----关于注入HTML

    后台接口返回了一个HTML字符串&#xff0c;要绑定到页面&#xff0c;第一时间想到了innerHTML... 一&#xff1a;先说下一般用法 //原生用法 <div id"content"></div> document.getElementById("content").innerHTML"需显示的内容"&…...

    2024/3/17 2:27:23
  6. angular 兼容ie11 ie11兼容

    欢迎加入前端交流群交流知识获取视频资料&#xff1a;749539640 兼容一&#xff08;new Date()用法) new Date(2018-01-01 00:00:00).getHours(); new Date(2018-01-01 00:00:00).getMinutes(); new Date(2018-01-01 00:00:00).getSeconds(); 在IE11下需要这么写 let myMinTime…...

    2024/3/16 0:04:00
  7. 割全切双眼皮拆线疼吗

    ...

    2024/3/15 5:51:12
  8. 割哪种双眼皮最好看

    ...

    2024/3/16 0:03:59
  9. 割了双眼皮肿的历害图片

    ...

    2024/3/16 0:03:58
  10. 割了割了双眼皮之后扎眼睛

    ...

    2024/3/16 0:03:55
  11. 割了双眼皮怎样洗眼睛

    ...

    2024/3/13 15:30:46
  12. django 非常实用的无限级分类功能

    利用model中的save方法&#xff0c;变相的实现递归循环&#xff0c;所有子分类都能在其中更新&#xff0c;感觉挺巧妙&#xff0c;之前的实现方式确实太烂了。 order的方法竟然支持1:23:2 这种方式的排序&#xff0c;轻松解决以前靠order_id排序的弊端。精简了代码。 其中一…...

    2024/3/14 11:25:39
  13. 基于vue element table 分级显示

    前一阵子我们的产品出了迭代的需求&#xff0c;然后我成功的从angular 转到 vue 了&#xff08;吐槽一下&#xff09; 然后有一个需求是这样的 一级部门 二级部门 领导 相关人员 数据格式如下 &#xff1a; 那element table 不接受二维数组&#xff0c;那我应该怎么去实现这个…...

    2024/3/15 18:14:44
  14. 用vue-router实现二级菜单内容的转换

    二级菜单导航是一种很普遍的功能&#xff0c;一般网页都会有这个功能。如果是平常的做法就是改变url&#xff0c;跳到相应的页面&#xff1b;还有一种就是frame。 如果用vue的话&#xff0c;可以用vue-router改变<router-view>里面的组件&#xff0c;这样就能做到不刷新…...

    2024/3/17 16:48:08
  15. 割了双眼皮怎么恢复快

    ...

    2024/3/20 7:00:47
  16. 割了双眼皮淤青怎么办

    ...

    2024/3/26 4:30:39
  17. 记录简单优化系——关于图表请求页面加载缓慢问题的追查(stalled 时间过长)

    问题描述&#xff1a;一个页面中有多个图表&#xff0c;用到的是echarts&#xff0c;angularjs&#xff0c;每一个图表都是一个请求&#xff0c;详细如截图。 发现stalled&#xff08;阻塞&#xff09;时间比较长&#xff0c;上网百度可以得到很多解决办法&#xff0c;简单百度…...

    2024/3/16 0:03:52
  18. 割了双眼皮有眼袋

    ...

    2024/3/16 0:03:53
  19. 割了双眼皮用什么热敷

    ...

    2024/3/16 0:03:50
  20. 割了双眼皮用什么冰敷

    ...

    2024/3/16 0:03:49

最新文章

  1. STM32时钟简介

    1、复位&#xff1a;使时钟恢复原始状态 就是将寄存器状态恢复到复位值 STM32E10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位。 复位分类&#xff1a; 1.1系统复位 除了时钟控制器的RCC_CSR寄存器中的复位标志位和备份区域中的寄存器以外,系统 复位将复位…...

    2024/3/29 9:37:23
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 2024.3.21 QT

    QT登录界面设计&#xff1a; //头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMovie>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nu…...

    2024/3/29 3:30:19
  4. c++基础学习第六天(多态,文件操作,模板)

    c基础学习第天&#xff08;多态&#xff0c;文件操作&#xff0c;模板&#xff09; 文章目录 1、多态1.1、多态的基本概念1.2、纯虚函数和抽象类1.3、虚析构和纯虚析构 2、文件操作2.1、文本文件2.1.1、写文件2.1.2、读文件 2.2、二进制文件2.2.1、写文件2.2.2、读文件 C提高编…...

    2024/3/29 3:32:01
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/3/27 10:21:24
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/3/24 20:11:25
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/3/29 2:45:46
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/3/24 20:11:23
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/3/29 5:19:52
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/3/28 17:01:12
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/3/24 5:55:47
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/3/29 1:13:26
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/3/29 8:28:16
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/3/29 7:41:19
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/3/24 20:11:18
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/3/28 9:10:53
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/3/29 0:49:46
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/3/24 20:11:15
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/3/27 7:12:50
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/3/24 20:11:13
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/3/26 11:21:23
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/3/28 18:26:34
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/3/28 12:42:28
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/3/28 20:09:10
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57