理解ASP.NET Core 啟動類(Startup)
準(zhǔn)備工作:一份ASP.NET Core Web API應(yīng)用程序
當(dāng)我們來到一個陌生的環(huán)境,第一件事就是找到廁所在哪。
當(dāng)我們接觸一份新框架時,第一件事就是找到程序入口,即Main方法
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
代碼很簡單,典型的建造者模式:通過IHostBuilder創(chuàng)建一個通用主機(Generic Host),然后啟動它(至于什么是通用主機,咱們后續(xù)的文章會說到)。咱們不要一上來就去研究CreateDefaultBuilder、ConfigureWebHostDefaults這些方法的源代碼,應(yīng)該去尋找能看的見、摸得著的,很明顯,只有Startup。
Startup類
Startup類承擔(dān)應(yīng)用的啟動任務(wù),所以按照約定,起名為Startup,不過你可以修改為任意類名(強烈建議類名為Startup)。
默認(rèn)的Startup結(jié)構(gòu)很簡單,包含:
- 構(gòu)造函數(shù)
Configuration屬性ConfigureServices方法Configure方法
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// 該方法由運行時調(diào)用,使用該方法向DI容器添加服務(wù)
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// 該方法由運行時調(diào)用,使用該方法配置HTTP請求管道
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
}
Startup構(gòu)造函數(shù)
當(dāng)使用通用主機(Generic Host)時,Startup構(gòu)造函數(shù)支持注入以下三種服務(wù)類型:
IConfigurationIWebHostEnvironmentIHostEnvironment
public Startup(
IConfiguration configuration,
IHostEnvironment hostEnvironment,
IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
HostEnvironment = hostEnvironment;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IHostEnvironment HostEnvironment { get; set; }
public IWebHostEnvironment WebHostEnvironment { get; set; }
這里你會發(fā)現(xiàn) HostEnvironment 和 WebHostEnvironment 的實例是同一個。別著急,后續(xù)文章我們聊到Host的時候,你就明白了。
ConfigureServices
- 該方法是可選的
- 該方法用于添加服務(wù)到DI容器中
- 該方法在
Configure方法之前被調(diào)用 - 該方法要么無參數(shù),要么只能有一個參數(shù)且類型必須為
IServiceCollection - 該方法內(nèi)的代碼大多是形如
Add{Service}的擴展方法
常用的服務(wù)有(部分服務(wù)框架已默認(rèn)注冊):
AddControllers:注冊Controller相關(guān)服務(wù),內(nèi)部調(diào)用了AddMvcCore、AddApiExplorer、AddAuthorization、AddCors、AddDataAnnotations、AddFormatterMappings等多個擴展方法AddOptions:注冊O(shè)ptions相關(guān)服務(wù),如IOptions<>、IOptionsSnapshot<>、IOptionsMonitor<>、IOptionsFactory<>、IOptionsMonitorCache<>等。很多服務(wù)都需要Options,所以很多服務(wù)注冊的擴展方法會在內(nèi)部調(diào)用AddOptionsAddRouting:注冊路由相關(guān)服務(wù),如IInlineConstraintResolver、LinkGenerator、IConfigureOptions<RouteOptions>、RoutePatternTransformer等AddAddLogging:注冊Logging相關(guān)服務(wù),如ILoggerFactory、ILogger<>、IConfigureOptions<LoggerFilterOptions>>等AddAuthentication:注冊身份認(rèn)證相關(guān)服務(wù),以方便后續(xù)注冊JwtBearer、Cookie等服務(wù)AddAuthorization:注冊用戶授權(quán)相關(guān)服務(wù)AddMvc:注冊Mvc相關(guān)服務(wù),比如Controllers、Views、RazorPages等AddHealthChecks:注冊健康檢查相關(guān)服務(wù),如HealthCheckService、IHostedService等
Configure
- 該方法是必須的
- 該方法用于配置HTTP請求管道,通過向管道添加中間件,應(yīng)用不同的響應(yīng)方式。
- 該方法在
ConfigureServices方法之后被調(diào)用 - 該方法中的參數(shù)可以接受任何已注入到DI容器中的服務(wù)
- 該方法內(nèi)的代碼大多是形如
Use{Middleware}的擴展方法 - 該方法內(nèi)中間件的注冊順序與代碼的書寫順序是一致的,先注冊的先執(zhí)行,后注冊的后執(zhí)行
常用的中間件有
UseDeveloperExceptionPage:當(dāng)發(fā)生異常時,展示開發(fā)人員異常信息頁。如圖

UseRouting:路由中間件,根據(jù)Url中的路徑導(dǎo)航到對應(yīng)的Endpoint。必須與UseEndpoints搭配使用。UseEndpoints:執(zhí)行路由所選擇的Endpoint對應(yīng)的委托。UseAuthentication:身份認(rèn)證中間件,用于對請求用戶的身份進行認(rèn)證。比如,早晨上班打卡時,管理員認(rèn)出你是公司員工,那么才允許你進入公司。UseAuthorization:用戶授權(quán)中間件,用于對請求用戶進行授權(quán)。比如,雖然你是公司員工,但是你是一名.NET開發(fā)工程師,那么你只允許坐在.NET開發(fā)工程師區(qū)域的工位上,而不能坐在老總的辦公室里。UseMvc:Mvc中間件。UseHealthChecks:健康檢查中間件。UseMiddleware:用來添加匿名中間件的,通過該方法,可以方便的添加自定義中間件。
省略Startup類
另外,Startup類也可以省略,直接進行如下配置即可(雖然可以這樣做,但是不推薦):
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// ConfigureServices 可以調(diào)用多次,最終會將結(jié)果聚合
webBuilder.ConfigureServices(services =>
{
})
// Configure 如果調(diào)用多次,則只有最后一次生效
.Configure(app =>
{
var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
});
});
IStartupFilter
public interface IStartupFilter
{
Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next);
}
有時,我們想要將一系列相關(guān)中間件的注冊封裝到一起,那么我們只需要通過實現(xiàn)IStartupFilter,并在Startup.ConfigureServices中配置IStartupFilter的依賴注入即可。
- 在
IStartupFilter中配置的中間件,總是比Startup類中Configure方法中的中間件先注冊;對于多個IStartupFilter實現(xiàn),執(zhí)行順序與服務(wù)注冊時的順序一致
我們可以通過一個例子來驗證一下中間件的注冊順序。
首先是三個IStartupFilter的實現(xiàn)類:
public class FirstStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
=> app =>
{
app.Use((context, next) =>
{
Console.WriteLine("First");
return next();
});
next(app);
};
}
public class SecondStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
=> app =>
{
app.Use((context, next) =>
{
Console.WriteLine("Second");
return next();
});
next(app);
};
}
public class ThirdStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
=> app =>
{
app.Use((context, next) =>
{
Console.WriteLine("Third");
return next();
});
next(app);
};
}
接下來進行注冊:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// 第一個被注冊
services.AddTransient<IStartupFilter, FirstStartupFilter>();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureServices(services =>
{
// 第三個被注冊
services.AddTransient<IStartupFilter, ThirdStartupFilter>();
});
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 第二個被注冊
services.AddTransient<IStartupFilter, SecondStartupFilter>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 第四個被注冊
app.Use((context, next) =>
{
Console.WriteLine("Forth");
return next();
});
}
}
最后通過輸出可以看到,執(zhí)行順序的確是這樣子的。
First
Second
Third
Forth
IHostingStartup
與IStartupFilter不同的是,IHostingStartup可以在啟動時通過外部程序集向應(yīng)用增加更多功能。不過這要求必須調(diào)用ConfigureWebHost、ConfigureWebHostDefaults等類似用來配置Web主機的擴展方法
我們經(jīng)常使用的Nuget包
SkyApm.Agent.AspNetCore就使用了該特性。
下面我們就來看一下該如何使用它。
HostingStartup 程序集
要創(chuàng)建HostingStartup程序集,可以通過創(chuàng)建類庫項目或無入口點的控制臺應(yīng)用來實現(xiàn)。
接下來咱們還是看一下上面提到過的SkyApm.Agent.AspNetCore:
using SkyApm.Agent.AspNetCore;
[assembly: HostingStartup(typeof(SkyApmHostingStartup))]
namespace SkyApm.Agent.AspNetCore
{
internal class SkyApmHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services => services.AddSkyAPM(ext => ext.AddAspNetCoreHosting()));
}
}
}
該HostingStartup類:
- 實現(xiàn)了
IHostingStartup接口 Configure方法中使用IWebHostBuilder來添加增強功能- 配置了
HostingStartup特性
HostingStartup 特性
HostingStartup特性用于標(biāo)識哪個類是HostingStartup類,HostingStartup類需要實現(xiàn)IHostingStartup接口。
當(dāng)程序啟動時,會自動掃描入口程序集和配置的待激活的的程序集列表(參見下方:激活HostingStarup程序集),來找到所有的HostingStartup特性,并通過反射的方式創(chuàng)建Startup并調(diào)用Configure方法。
using SkyApm.Agent.AspNetCore;
[assembly: HostingStartup(typeof(SkyApmHostingStartup))]
namespace SkyApm.Agent.AspNetCore
{
internal class SkyApmHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services => services.AddSkyAPM(ext => ext.AddAspNetCoreHosting()));
}
}
}
激活HostingStarup程序集
要激活HostingStarup程序集,我們有兩種配置方式:
1.使用環(huán)境變量(推薦)
使用環(huán)境變量,無需侵入程序代碼,所以我更推薦大家使用這種方式。
配置環(huán)境變量ASPNETCORE_HOSTINGSTARTUPASSEMBLIES,多個程序集使用分號(;)進行分隔,用于添加要激活的程序集。變量WebHostDefaults.HostingStartupAssembliesKey就是指代這個環(huán)境變量的Key。
另外,還有一個環(huán)境變量,叫做ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES,多個程序集使用分號(;)進行分隔,用于排除要激活的程序集。變量WebHostDefaults.HostingStartupExcludeAssembliesKey就是指代這個環(huán)境變量的Key。
我們在 launchSettings.json 中添加兩個程序集:
"environmentVariables": {
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SkyAPM.Agent.AspNetCore;HostingStartupLibrary"
}
2.在程序中配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseSetting(
WebHostDefaults.HostingStartupAssembliesKey,
"SkyAPM.Agent.AspNetCore;HostingStartupLibrary")
.UseStartup<Startup>();
});
這樣就配置完成了,很🐮🍺的一個功能點吧!
需要注意的是,無論使用哪種配置方式,當(dāng)存在多個HostingStartup程序集時,將按配置這些程序集時的書寫順序執(zhí)行 Configure方法。
多環(huán)境配置
一款軟件,一般要經(jīng)過需求分析、設(shè)計編碼,單元測試、集成測試以及系統(tǒng)測試等一系列測試流程,驗收,最終上線。那么,就至少需要4套環(huán)境來保證系統(tǒng)運行:
Development:開發(fā)環(huán)境,用于開發(fā)人員在本地對應(yīng)用進行調(diào)試運行Test:測試環(huán)境,用于測試人員對應(yīng)用進行測試Staging:預(yù)發(fā)布環(huán)境,用于在正式上線之前,對應(yīng)用進行集成、測試和預(yù)覽,或用于驗收Production:生產(chǎn)環(huán)境,應(yīng)用的正式線上環(huán)境
環(huán)境配置方式
通過環(huán)境變量ASPNETCORE_ENVIRONMENT指定運行環(huán)境
注意:如果未指定環(huán)境,默認(rèn)情況下,為 Production
在項目的Properties文件夾里面,有一個“l(fā)aunchSettings.json”文件,該文件是用于配置VS中項目啟動的。
接下來我們就在launchSettings.json中配置一下。
先解釋一下該文件中出現(xiàn)的幾個參數(shù):
commandName:指定要啟動的Web服務(wù)器,有三個可選值:
Project:啟動 Kestrel
IISExpress:啟動IIS Express
IIS:不啟用任何Web服務(wù)器,使用IIS
dotnetRunMessages:bool字符串,指示當(dāng)使用 dotnet run 命令時,終端能夠及時響應(yīng)并輸出消息,具體參考stackoverflow和github issuelaunchBrowser:bool值,指示當(dāng)程序啟動后,是否打開瀏覽器launchUrl:默認(rèn)啟動路徑applicationUrl:應(yīng)用程序Url列表,多個URL之間使用分號(;)進行分隔。當(dāng)launchBrowser為true時,將{applicationUrl}/{launchUrl}作為瀏覽器默認(rèn)訪問的UrlenvironmentVariables:環(huán)境變量集合,在該集合內(nèi)配置環(huán)境變量
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
// 如果不指定profile,則默認(rèn)選擇第一個
// Development
"ASP.NET.WebAPI": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
// Test
"ASP.NET.WebAPI.Test": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test"
}
},
// Staging
"ASP.NET.WebAPI.Staging": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Staging"
}
},
// Production
"ASP.NET.WebAPI.Production": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
// 用于測試在未指定環(huán)境時,默認(rèn)是否為Production
"ASP.NET.WebAPI.Default": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000"
}
}
}
配置完成后,就可以在VS上方工具欄中的項目啟動處選擇啟動項了
基于環(huán)境的 Startup
Startup類支持針對不同環(huán)境進行個性化配置,有三種方式:
- 1.將
IWebHostEnvironment注入 Startup 類 - 2.Startup 方法約定
- 3.Startup 類約定
1.將IWebHostEnvironment注入 Startup 類
通過將IWebHostEnvironment注入 Startup 類,然后在方法中使用條件判斷書寫不同環(huán)境下的代碼。該方式適用于多環(huán)境下,代碼差異較少的情況。
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
if (WebHostEnvironment.IsDevelopment())
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
else if (WebHostEnvironment.IsTest())
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
else if (WebHostEnvironment.IsStaging())
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
else if (WebHostEnvironment.IsProduction())
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
}
public void Configure(IApplicationBuilder app)
{
if (WebHostEnvironment.IsDevelopment())
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
else if (WebHostEnvironment.IsTest())
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
else if (WebHostEnvironment.IsStaging())
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
else if (WebHostEnvironment.IsProduction())
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
}
}
public static class AppHostEnvironmentEnvExtensions
{
public static bool IsTest(this IHostEnvironment hostEnvironment)
{
if (hostEnvironment == null)
{
throw new ArgumentNullException(nameof(hostEnvironment));
}
return hostEnvironment.IsEnvironment(AppEnvironments.Test);
}
}
public static class AppEnvironments
{
public static readonly string Test = nameof(Test);
}
2.Startup 方法約定
上面的方式把不同環(huán)境的代碼放在了同一個方法中,看起來比較混亂也不容易區(qū)分。因此我們希望ConfigureServices和Configure能夠根據(jù)不同的環(huán)境進行代碼拆分。
我們可以通過方法命名約定來解決,約定Configure{EnvironmentName}Services和Configure{EnvironmentName}Services來裝載不同環(huán)境的代碼。如果當(dāng)前環(huán)境沒有對應(yīng)的方法,則使用原來的ConfigureServices和Configure方法。
我就只拿 Development 和 Production 舉例了
public class Startup
{
// 我這里注入 IWebHostEnvironment,僅僅是為了打印出來當(dāng)前環(huán)境信息
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; }
#region ConfigureServices
private void StartupConfigureServices(IServiceCollection services)
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
public void ConfigureDevelopmentServices(IServiceCollection services)
{
StartupConfigureServices(services);
}
public void ConfigureProductionServices(IServiceCollection services)
{
StartupConfigureServices(services);
}
public void ConfigureServices(IServiceCollection services)
{
StartupConfigureServices(services);
}
#endregion
#region Configure
private void StartupConfigure(IApplicationBuilder app)
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
public void ConfigureDevelopment(IApplicationBuilder app)
{
StartupConfigure(app);
}
public void ConfigureProduction(IApplicationBuilder app)
{
StartupConfigure(app);
}
public void Configure(IApplicationBuilder app)
{
StartupConfigure(app);
}
#endregion
}
3.Startup 類約定
該方式適用于多環(huán)境下,代碼差異較大的情況。
程序啟動時,會優(yōu)先尋找當(dāng)前環(huán)境命名符合Startup{EnvironmentName}的 Startup 類,如果找不到,則使用名稱為Startup的類
首先,CreateHostBuilder方法需要做一處修改
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
//webBuilder.UseStartup<Startup>();
webBuilder.UseStartup(typeof(Startup).GetTypeInfo().Assembly.FullName);
});
接下來,就是為各個環(huán)境定義 Startup 類了(我就只拿 Development 和 Production 舉例了)
public class StartupDevelopment
{
// 我這里注入 IWebHostEnvironment,僅僅是為了打印出來當(dāng)前環(huán)境信息
public StartupDevelopment(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
public void Configure(IApplicationBuilder app)
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
}
public class StartupProduction
{
public StartupProduction(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine($"{nameof(ConfigureServices)}: {WebHostEnvironment.EnvironmentName}");
}
public void Configure(IApplicationBuilder app)
{
Console.WriteLine($"{nameof(Configure)}: {WebHostEnvironment.EnvironmentName}");
}
}
到此這篇關(guān)于理解ASP.NET Core 啟動類(Startup)的文章就介紹到這了,更多相關(guān)ASP.NET Core Startup內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.Net MVC+Data Table實現(xiàn)分頁+排序功能的方法
這篇文章主要介紹了ASP.Net MVC+Data Table實現(xiàn)分頁+排序功能的方法,結(jié)合實例形式分析了asp.net基于mvc架構(gòu)實現(xiàn)的數(shù)據(jù)查詢、排序、分頁顯示等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
ASP.NET Core應(yīng)用錯誤處理之ExceptionHandlerMiddleware中間件呈現(xiàn)“定制化錯誤頁面”
這篇文章主要給大家介紹了關(guān)于ASP.NET Core應(yīng)用錯誤處理之ExceptionHandlerMiddleware中間件呈現(xiàn)“定制化錯誤頁面”的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧2019-01-01
asp.net(c#)動態(tài)修改webservice的地址和端口(動態(tài)修改配置文件)
這個問題其實并沒有我想像的那個復(fù)雜,我們都知道怎么直接修改吧,那就是修改WebConfig文件的配置節(jié)2012-12-12
.NET讀寫Excel工具Spire.Xls使用 對數(shù)據(jù)操作與控制(4)
這篇文章主要為大家詳細(xì)介紹了.NET讀寫Excel工具Spire.Xls使用,對數(shù)據(jù)操作與控制的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
asp.net為網(wǎng)頁動態(tài)添加description描述信息的方法
這篇文章主要介紹了asp.net為網(wǎng)頁動態(tài)添加description描述信息的方法,涉及asp.net動態(tài)操作網(wǎng)頁元素的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-04-04
Entity Framework加載控制Loading Entities
本文詳細(xì)講解了Entity Framework加載控制Loading Entities的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03
詳解Asp.net web.config customErrors 如何設(shè)置
這篇文章主要介紹了詳解Asp.net web.config customErrors 如何設(shè)置,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02

