GVKun编程网logo

StartMVC

10

对于想了解StartMVC的读者,本文将是一篇不可错过的文章,并且为您提供关于.netcoremvc启动顺序以及主要部件3-Startup、ASP.NETMVC入门-Startup类:注册服务和使用中

对于想了解StartMVC的读者,本文将是一篇不可错过的文章,并且为您提供关于.net core mvc启动顺序以及主要部件3-Startup、ASP.NET MVC 入门 - Startup 类:注册服务和使用中间件、ASP.NET MVC中_ViewStart.cshtml作用介绍、ASP.NET MVC教程八:_ViewStart.cshtml的有价值信息。

本文目录一览:

StartMVC

StartMVC

a03fbd0f272ec563a545ab568995c1eb_557x223.jpg

StartMVC是一款超轻量PHP7框架,面向对象开发,小巧、优雅、高效,遵循 Apache2 开源协议发布的,支持 Composer 和 RESTful 的 PHP 开源框架。

StartMVC 能够帮助开发者以最小的学习成本快速构建 Web 应用,在满足开发者最基础的分层开发、数据库和缓存访问等少量功能基础上,做到尽可能精简,以帮助您的应用基于框架高效运行。

优势

轻量极致,可以高效地运行,打包后只有50k

完全支持Composer,代码遵循ps2,psr4规范,方便扩展第三方类库。

官方免费提供常用的扩展类库下载,拿来即用。

数据库采用PDO操作,支持多种数据库。

支持多应用、扩展机制、路由分发、自动加载、RESTFul Api、缓存、MVC结构和依赖注入。。

采用原生 PHP语法作为视图引擎,您不必再去学习模板语法!系统运行效率极大提高!

松耦合,执行效率更高。

系统结构简洁,代码优雅规范。

学习成本低,只要有一点PHP基码就可以迅速上手。

StartMVC官方网站

官方网站:https://startmvc.com/

如果觉得小编网站内容还不错,欢迎将小编网站 推荐给程序员好友。

.net core mvc启动顺序以及主要部件3-Startup

.net core mvc启动顺序以及主要部件3-Startup

前面分享了.net core Program类的启动过程已经源代码介绍,这里将继续讲Startup类中的两个约定方法,一个是ConfigureServices,这个方法是用来写我们应用程序所依赖的组件。另一个Configure,它是我们MVC请求的中间件方法,也就是我们每个请求来要执行的过程都可以写在这个方法里面。
      为什么说Startup类中的两个方法是基于约定的呢?其实是这样的,在.net core Program类Main方法中有个调用了Run方法这个方法从IServiceCollection容器中拿到一个IStartup类型的实例然后调用了IStartup中定义的两个方法法,如果我们的Startup类是实现了这个接口的类 那么就不是基于约定了,直接就可以使用,但是我们发现在vs给我们生成的Startup类并没有实现任何接口,所以就不会是IStartup类型,那么内部是如何去做的呢?  其实是这样的,在注册Startup实例的时候还有个类型叫做ConventionBasedStartup从名称上解读这个类就是转换为基础的Startup,其实却是也是这样的,这个类中是实现了IStartup接口,它的两个方法中分别调用了各自的对用委托,这些委托实际执行的就是我们Startup类中定义的两个方法,请看源代码:

public class ConventionBasedStartup : IStartup
    {
        private readonly StartupMethods _methods;

        public ConventionBasedStartup(StartupMethods methods)
        {
            _methods = methods;
        }

        public void Configure(IApplicationBuilder app)
        {
            try
            {
                _methods.ConfigureDelegate(app);
            }
            catch (Exception ex)
            {
                if (ex is TargetInvocationException)
                {
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                }
                throw;
            }
        }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            try
            {
                return _methods.ConfigureServicesDelegate(services);
            }
            catch (Exception ex)
            {
                if (ex is TargetInvocationException)
                {
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                }
                throw;
            }
        }
    }

  现在Startup类的方法说清楚了,我们具体来说说方法中的内容,首先说ConfigureServices(IServiceCollection services),这个方法的参数是约定好的,不能随意改变,里面的IServiceCollection接口其实就是我们依赖注入的容器,说的再直白一点就是我们整个MVC所需要的实例都由IServiceCollection所管理,IServiceCollection有几个重要的扩展方法,他们都是定义在ServiceCollectionServiceExtensions静态类中,AddTransient方法,表示用这个方法添加到IServiceCollection容器的实例在需要注入的实例中都是一个全新的实例,AddScoped方法,这个方法表示在一次请求的生命周期内共用一个实例,AddSingleton方法,这个方法表示整个程序共用一个实例,例如日志服务,IConfiguration服务等都属于典型Singleton。请看例子:

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<TransientService>();
            services.AddTransient<ServiceDemo1>();
            services.AddTransient<ServiceDemo2>();
        }

        public void Configure(IApplicationBuilder app, ServiceDemo1 demo1, ServiceDemo2 demo2 )
        {
            demo1.Test();
            demo2.Test();
            app.Run(async (HttpContext context) =>
            {
              await  context.Response.WriteAsync("test successd");
            });
        }
    }
    public class TransientService
    {
        private int _updateCount;
        public int GetUpdateCount()
        {   
this._updateCount = this._updateCount + 1; return this._updateCount; } } public class ServiceDemo1 { private readonly TransientService _service; public ServiceDemo1(TransientService service) { _service = service; } public void Test() { Console.WriteLine($"我是demo1的计数:{this._service.GetUpdateCount()}"); } } public class ServiceDemo2 { private readonly TransientService _service; public ServiceDemo2(TransientService service) { _service = service; } public void Test() { Console.WriteLine($"我是demo2的计数:{this._service.GetUpdateCount()}"); } }

  上面的例子中会产生一下结果,可以看得出来这两个注入的TransientService都是全新的实例

如果我们稍微改变一下注入的方法,将原本的 services.AddTransient<TransientService>();改成services.AddScoped<TransientService>();就会产生如下结果:

这个能说明什么呢,我们有两次注入  这个就表示TransientService保持了之前demo1的状态  demo1和demo2是可以共用这个实例来传输数据的,AddSingleton方法理解起来比较简单就不过多絮叨了,上面已经说明。

接下来再来说说Startup类中的Configure方法,Configure方法中的参数是可以变化的,也就是说你可以用依赖注入的方法在参数中注入你想要注入的实例,前面说了 这个方法是我们请求的中间件方法,这个方法中会整合我们注入的IApplicationBuilder 中调用的各种Use方法中定义的中间件  并不是说这里面定义的代码每次请求都会被执行,这个概念一定要搞清楚,Configure方法只会在启动的时候执行一次,后面就不会再执行了,Configure方法只是让我们可以定义整个MVC的处理请求的执行顺序,具体的可以看看官方的文档https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2

其实中间件都是由IApplicationBuilder 所管理的ApplicationBuilder类实现了IApplicationBuilder 接口中的方法,看到ApplicationBuilder中的源代码中有个属性_components 它是一个IList<Func<RequestDelegate, RequestDelegate>>类型的委托容器,容器中的委托就是请求过来需要执行的中间件委托,当你在Configure方法中调用app.UseXXX的时候就会被注册到这个容器中去,然后请求过来就按照顺序执行容器中的每一个委托,所以这里就解释了前面说的Configure方法只会被执行一次的说法。下面也贴一下ApplicationBuilder类的源代码:

public class ApplicationBuilder : IApplicationBuilder
    {
        private readonly IList<Func<RequestDelegate, RequestDelegate>> _components = new List<Func<RequestDelegate, RequestDelegate>>();

        public IServiceProvider ApplicationServices
        {
            get
            {
                return GetProperty<IServiceProvider>(Constants.BuilderProperties.ApplicationServices);
            }
            set
            {
                SetProperty(Constants.BuilderProperties.ApplicationServices, value);
            }
        }

        public IFeatureCollection ServerFeatures => GetProperty<IFeatureCollection>(Constants.BuilderProperties.ServerFeatures);

        public IDictionary<string, object> Properties
        {
            get;
        }

        public ApplicationBuilder(IServiceProvider serviceProvider)
        {
            Properties = new Dictionary<string, object>(StringComparer.Ordinal);
            ApplicationServices = serviceProvider;
        }

        public ApplicationBuilder(IServiceProvider serviceProvider, object server)
            : this(serviceProvider)
        {
            SetProperty(Constants.BuilderProperties.ServerFeatures, server);
        }

        private ApplicationBuilder(ApplicationBuilder builder)
        {
            Properties = new CopyOnWriteDictionary<string, object>(builder.Properties, StringComparer.Ordinal);
        }

        private T GetProperty<T>(string key)
        {
            if (!Properties.TryGetValue(key, out object value))
            {
                return default(T);
            }
            return (T)value;
        }

        private void SetProperty<T>(string key, T value)
        {
            Properties[key] = value;
        }

        public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
        {
            _components.Add(middleware);
            return this;
        }

        public IApplicationBuilder New()
        {
            return new ApplicationBuilder(this);
        }

        public RequestDelegate Build()
        {
            RequestDelegate requestDelegate = delegate (HttpContext context)
            {
                context.Response.StatusCode = 404;
                return Task.CompletedTask;
            };
            foreach (Func<RequestDelegate, RequestDelegate> item in _components.Reverse())
            {
                requestDelegate = item(requestDelegate);
            }
            return requestDelegate;
        }
    }

好啦,这篇关于Startup类就算介绍完成了,下篇开始正式介绍MVC



ASP.NET MVC 入门 - Startup 类:注册服务和使用中间件

ASP.NET MVC 入门 - Startup 类:注册服务和使用中间件

笔记内容来源于微软 MVP 杨旭老师 solenovex 的视频

Startup 类:注册服务和使用中间件

Startup 类默认生成了两个方法,在这个类中主要负责注册服务和使用中间件。

让我们先来看一下 Startup 类的源码

Startup 类的源码

在下面的源码中有 ConfigureServices 和 Configure 两个方法。

public void ConfigureServices(IServiceCollection services){}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Hello World!");
    });
}

 

1.ConfigureServices 方法

ConfigureServices 方法是用来注册服务的,Configure 方法是用来使用中间件的。

注册服务就是依赖注入,向 Ioc 容器中注入类型的对象,注入后就可以直接使用该类型注入实例,而无需再次实例化,减少了代码的耦合。

具体内容可以自行百度依赖注入 / 控制反转。

2.Configure 方法

Configure 方法配置了 Http 请求处理的管道,每个 Http 请求到达之后,会按照 Configure 方法中的组件来决定如何处理这些请求。

其中的 app.Run 方法以及匿名函数,就是不管什么请求到达这里,都会返回 context.Response.WriteAsync("Hello World!") 响应。

注册服务演示

我们先创建一个 IWelcomeService 接口以及实现该接口的 WelcomeService 类

public interface IWelcomeService
{
    string GetMessage();
}
public class WelcomeService : IWelcomeService
{
    public string GetMessage()
    {
        return "Hello from IWelcomeService";
    }
}

 

然后在 Startup 类 Configure 方法中使用该接口类型对象,调用接口的 GetMessage 方法输出

事实上,运行后我们会发现直接使用是不行的,因为该类型刚还有在 ConfigureServices 方法中注册。

下面我们就在 ConfigureServices 方法中注册接口和实现类。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IWelcomeService, WelcomeService>();
}

 

运行后的结果

Hello from IWelcomeService

注册服务的几种形式

注册服务时,我们使用的是 AddSingleton 方法,这是以单例的形式依赖注入对象,单例就是指该类型只有一个实例,具体含义和用法可以自行百度。

还有其他几种形式,如 AddTransient 方法,每次请求都会生成一个实例,AddScoped 方法,每次 Http 请求都会生成一个实例。

管道和中间件

Configure 方法配置了 Http 请求处理的管道。

假设有个 Http 请求到达了我们的 Web 应用,有一个 POST 请求,那么我们的 Web 应用就需要处理这个请求。中间件就是负责处理请求的,他将决定如何处理这些请求。

中间件其实就是个对象,每个中间件的角色和功能都不一样,并且局限在特定的领域内。每个中间件都很小,Web 应用会用到很多中间件。

一个简单的中间件管道示例

假设一个 POST 请求 Product,首先通过 Logger 中间件,Logger 可以查看到很多的信息,记录下请求的信息,也可以拒绝请求。

然后转送到下个中间件,比如授权中间件。授权中间件会先找一个特定的 cookie 的值或者 token,如果找到了就转发到下一个中间件。

下一个中间件可以是路由中间件。首先查看请求的 URL,然后找到可以响应该请求的方法,就可以返回一个 JSON/HTML,然后原路返回。

Startup 类被调用的逻辑

搞清了 Startup 类中的方法的作用和能做什么后,我们来看一看 Startup 类是如何被调用的。

上一篇博文提到了 Program 类的 CreateWebHostBuilder 方法中调用了  UseStartup<Startup>() ,就是这个方法制定了 Startup 类为启动类,实例化 Starup 类得到实例,并调用类中的两个方法。

首先会调用 ConfigureServices 方法,注册服务。除了预先注册好的服务,自己写的类和一些没注册内置类都需要在该方法中注册。

然后调用 Configure 方法,该方法只会调用一次。在该方法中,我们使用实现了 IApplicationBuilder 接口的类型的对象,来配置中间件。

中间件的 Use 方法

默认的 Run 方法并不建议使用,项目中常常使用 Use 方法。除此之外还有内置的很多 USeXxx 方法。如 UseWelcomePage 方法就会调用欢迎页。这些方法的参数往往可以传递一个对象来对其进行配置。

还有直接使用 Use 方法更底层,其参数是一个 Func<ReuquestDelegate,ReuquestDelegate>,Func 的参数是 ReuquestDelegate,

其返回类型也是 ReuquestDelegate。ReuquestDelegate 类型就是一段可执行的代码,例如下方代码,返回了一个异步 Task,Task 返回了 httpContext 对象。

app.Use(next => 
{
    return async httpContext =>
    {
        if (httpContext.Request.Path.StartsWithSegments("/first"))
        {
            await httpContext.Response.WriteAsync("First!");
        }
        else
        {
            await next(httpContext);
        }
    };
});

异常页面的中间件

下方代码首先判断当前环境是不是开发环境,如果是,当出现错误时就会使用开发者异常页面中间件。

因为开发者需要详细的错误信息,但是这些信息不能直接暴露,否则会被黑客轻易利用,因此只能在开发者环境下才需要调用开发者异常页面中间件。

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

判断环境和自定义环境

前面讲到可以判断运行环境,事实上环境是可以自定义的,

ASP.NET MVC中_ViewStart.cshtml作用介绍

ASP.NET MVC中_ViewStart.cshtml作用介绍

一、引言

_ViewStart.cshtml是在ASP.NET MVC 3.0及更高版本以后出现的,用Razor模板引擎新建项目后,Views目录下面会出现一个这样的文件:

打开_ViewStart.cshtml文件,里面只有一行代码:

这行代码表示使用Views文件夹下的Shared下面的_Layout.cshtml进行布局

二、作用

  • _ViewStart.cshtml是一个在呈现View文件的时候的启动文件,会在所有View(.cshtml)被执行之前执行,主要用于一些不方便或不能再母版(_Layout.cshtml)中进行的统一操作。譬如你有很多个没有继承关系的母版或不使用母版的单页。
  • 在_ViewStart.cshtml中,我们可以定义一些参数或做一些判断,定义过程、语法和普通的页面没有任何差别。
  • 在View被呈现的时候才会调用_ViewStart.cshtml,如果一个View是按照PartialView的方式输出的,则不会触发_ViewStart.cshtml中的代码。
  • 如果在Views的某个目录下(例如Home目录)也有一个同名的_ViewStart.cshtml文件,那么这个_ViewStart.cshtml也会被调用,但是最先被调用的还是最外面的_ViewStart.cshtml,然后才是Home目录下的_ViewStart.cshtml文件。

三、启动顺序

在Controller的Action方法上面添加断点调试,会发现_ViewStart.cshtml、Layout.cshtml、Index.cshtml三个视图页的执行顺序如下:

  • _ViewStart.cshtml
  • Index.cshtml
  • Layout.cshtml

四、测试

在新建一个视图的时候,会让你选择是否使用布局页,如果选择了布局页,那么就默认会使用_ViewStart.cshtml里面指定的布局视图:

这样设置就表示使用_ViewStart.cshtml里面指定的Layout布局页。

修改一下新创建的视图页代码

@{
    ViewBag.Title = "TestView";
}

<h2>这是测试视图页</h2>

然后浏览新创建的视图页

可以看到:除了我们刚才在视图页代码里面添加的一行文字意外,还有其它布局,这就是因为使用了布局页。

这时如果不想在使用布局页,那么就需要修改Layout了,修改代码如下:

@{
    ViewBag.Title = "TestView";
    // 指定Layout为null则表示不在使用布局页
    Layout = null;
}

<h2>这是测试视图页</h2>

在浏览页面

这时就不会使用布局页了。

如果新建视图的时候,不勾选使用布局页,则也不会使用

生成的视图页代码

@{
    // 这里自动设置Layout为null
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>TestViewWithNull</title>
</head>
<body>
    <div> 
        不使用布局页
    </div>
</body>
</html>

然后浏览新添加的视图

到此这篇关于ASP.NET MVC中_ViewStart.cshtml作用的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • ASP.NET MVC中的路由原理与用法
  • ASP.NET MVC中两个配置文件的作用详解
  • ASP.NET MVC中Controller控制器向View视图传值的几种方式
  • ASP.NET MVC项目部署方式介绍
  • ASP.NET MVC模式中应用程序结构详解
  • ASP.NET MVC模式简介
  • ASP.NET MVC过滤器执行顺序介绍
  • ASP.NET MVC自定义操作过滤器
  • ASP.NET MVC自定义授权过滤器

ASP.NET MVC教程八:_ViewStart.cshtml

ASP.NET MVC教程八:_ViewStart.cshtml

一、引言

_ViewStart.cshtml是在ASP.NET MVC 3.0及更高版本以后出现的,用Razor模板引擎新建项目后,Views目录下面会出现一个这样的文件:

打开_ViewStart.cshtml文件,里面只有一行代码:

这行代码表示使用Views文件夹下的Shared下面的_Layout.cshtml进行布局

二、作用

  1. _ViewStart.cshtml是一个在呈现View文件的时候的启动文件,会在所有View(.cshtml)被执行之前执行,主要用于一些不方便或不能再母版(_Layout.cshtml)中进行的统一操作。譬如你有很多个没有继承关系的母版或不使用母版的单页。
  2. 在_ViewStart.cshtml中,我们可以定义一些参数或做一些判断,定义过程、语法和普通的页面没有任何差别。
  3. 在View被呈现的时候才会调用_ViewStart.cshtml,如果一个View是按照PartialView的方式输出的,则不会触发_ViewStart.cshtml中的代码。
  4. 如果在Views的某个目录下(例如Home目录)也有一个同名的_ViewStart.cshtml文件,那么这个_ViewStart.cshtml也会被调用,但是最先被调用的还是最外面的_ViewStart.cshtml,然后才是Home目录下的_ViewStart.cshtml文件。

三、启动顺序

在Controller的Action方法上面添加断点调试,会发现_ViewStart.cshtml、Layout.cshtml、Index.cshtml三个视图页的执行顺序如下:

  1. _ViewStart.cshtml
  2. Index.cshtml
  3. Layout.cshtml

四、测试

在新建一个视图的时候,会让你选择是否使用布局页,如果选择了布局页,那么就默认会使用_ViewStart.cshtml里面指定的布局视图:

这样设置就表示使用_ViewStart.cshtml里面指定的Layout布局页。

修改一下新创建的视图页代码

@{
    ViewBag.Title = "TestView";
}

<h2>这是测试视图页</h2>

 然后浏览新创建的视图页

可以看到:除了我们刚才在视图页代码里面添加的一行文字意外,还有其它布局,这就是因为使用了布局页。

这时如果不想在使用布局页,那么就需要修改Layout了,修改代码如下:

@{
    ViewBag.Title = "TestView";
    // 指定Layout为null则表示不在使用布局页
    Layout = null;
}

<h2>这是测试视图页</h2>

 在浏览页面

这时就不会使用布局页了。

如果新建视图的时候,不勾选使用布局页,则也不会使用

生成的视图页代码

@{
    // 这里自动设置Layout为null
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>TestViewWithNull</title>
</head>
<body>
    <div> 
        不使用布局页
    </div>
</body>
</html>

 然后浏览新添加的视图

 

 

 

今天关于StartMVC的介绍到此结束,谢谢您的阅读,有关.net core mvc启动顺序以及主要部件3-Startup、ASP.NET MVC 入门 - Startup 类:注册服务和使用中间件、ASP.NET MVC中_ViewStart.cshtml作用介绍、ASP.NET MVC教程八:_ViewStart.cshtml等更多相关知识的信息可以在本站进行查询。

本文标签: