最近用angular和.net core 搭建一个前后端分离的BS框架,准备使用ABP模板实现。
因为准备前端代码也在VS2019里面写,所以此处勾上了One solution ...即前后端都放在一个解决方案里面。
2、创建后解压下载下来的安装包,打开刚才填的项目名的解决方案。如果数据库也在本机,则使用windows验证登录数据库创建一个按appsettings.json里面的数据库连接字符串中的数据库名在本机创建一个相应的数据库。后期要部署再其他数据库可以重新配置数据库连接字符串,用EF重新迁移数据库,用MySQL或者其他数据库需要安装相应EF 相关的数据库组件当然可能也会踩坑,此处不延申了。
3、用VS运行OPS02.Migrator迁移数据库,也可以用EF命令行 update-database迁移数据库(用命令行的时候注意选中 XXX.Migrator项目)
4、运行XXX.Web.Host项目,后端项目就跑起来了,可以在http://localhost:21021/swagger/index.html看到后端的一些webapi。
5、cmd命令行工具里面用cd命令进入XXX.Web.Host目录,运行npm install 命令(前提需要安装好node.js),运行此命令由于angular cli版本问题可能会出错,报错卸载angular重装,在搜到的卸载重装的命令执行了很多遍,我这边还是报错,看了一下项目 主要就是@angular-devkit/build-angular包没有安装上,单独执行npm install -save-dev @angular-devkit/build-angular安装还是报错,在卸载重装的时候需要清理angular安装cache,看cmd的报错猜想可能是angular-devkit/build-angular没清理干净,于是到 用户名\AppData\Roaming\npm\node_modules目录下面手动删掉angular-devkit/build-angular,再执行便npm install -save-dev @angular-devkit/build-angular安装成功了。然后执行npm start 访问http://localhost:4200 地址即可看到登录页面(执行npm start前需确保后端在运行中,否则前端项目启动时访问后端接口出错会加载不出页面)。输入用户名admin密码123qwe即可登录
5.前后端都在VS2019里面写在VS里面能同时启动运行前后端项目,可以修改XXX.Web.Host中的Startup.cs配置AspNetCore.SpaServices.AngularCli,在Startup.cs的IServiceProvider ConfigureServices(IServiceCollection services)方法中添加
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "./dist";
});
定义Spa静态文件根目录,
然后在Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)方法中配置使用Spa静态文件服务
app.UseStaticFiles();
最后配置使用Spa网页
app.UseSpa(spa =>
{
spa.Options.SourcePath = "./";
if (true)
{
spa.UseAngularCliServer(npmScript: "start");
}
});
配置完之后的Startup.cs如下,配置好之后即可以在VS启动XXX.Web.Host项目同时启动angular前端和ABP.net core 后端
usingSystem.IO;usingSystem;usingSystem.Linq;usingSystem.Reflection;usingMicrosoft.AspNetCore.Builder;usingMicrosoft.AspNetCore.Hosting;usingMicrosoft.Extensions.Configuration;usingMicrosoft.Extensions.DependencyInjection;usingMicrosoft.Extensions.Logging;usingCastle.Facilities.Logging;usingAbp.AspNetCore;usingAbp.AspNetCore.Mvc.Antiforgery;usingAbp.Castle.Logging.Log4Net;usingAbp.Extensions;usingOPS02.Configuration;usingOPS02.Identity;usingAbp.AspNetCore.SignalR.Hubs;usingAbp.Dependency;usingAbp.Json;usingMicrosoft.OpenApi.Models;usingNewtonsoft.Json.Serialization;usingMicrosoft.AspNetCore.SpaServices.AngularCli;namespaceOPS02.Web.Host.Startup
{public classStartup
{private const string _defaultCorsPolicyName = "localhost";private const string _apiVersion = "v1";private readonlyIConfigurationRoot _appConfiguration;publicStartup(IWebHostEnvironment env)
{
_appConfiguration=env.GetAppConfiguration();
}publicIServiceProvider ConfigureServices(IServiceCollection services)
{//MVC
services.AddControllersWithViews(
options=>{
options.Filters.Add(newAbpAutoValidateAntiforgeryTokenAttribute());
}
).AddNewtonsoftJson(options=>{
options.SerializerSettings.ContractResolver= newAbpMvcContractResolver(IocManager.Instance)
{
NamingStrategy= newCamelCaseNamingStrategy()
};
});
IdentityRegistrar.Register(services);
AuthConfigurer.Configure(services, _appConfiguration);
services.AddSignalR();//Configure CORS for angular2 UI
services.AddCors(
options=>options.AddPolicy(
_defaultCorsPolicyName,
builder=>builder
.WithOrigins(//App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
_appConfiguration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o=> o.RemovePostFix("/"))
.ToArray()
)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
)
);//Swagger - Enable this line and the related lines in Configure method to enable swagger UI
services.AddSwaggerGen(options =>{
options.SwaggerDoc(_apiVersion,newOpenApiInfo
{
Version=_apiVersion,
Title= "OPS02 API",
Description= "OPS02",//uncomment if needed TermsOfService = new Uri("https://example.com/terms"),
Contact = newOpenApiContact
{
Name= "OPS02",
Email= string.Empty,
Url= new Uri("https://twitter.com/aspboilerplate"),
},
License= newOpenApiLicense
{
Name= "MIT License",
Url= new Uri("https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/LICENSE"),
}
});
options.DocInclusionPredicate((docName, description)=> true);//Define the BearerAuth scheme that's in use
options.AddSecurityDefinition("bearerAuth", newOpenApiSecurityScheme()
{
Description= "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name= "Authorization",
In=ParameterLocation.Header,
Type=SecuritySchemeType.ApiKey
});
});
services.AddSpaStaticFiles(configuration=>{
configuration.RootPath= "./dist";
});//Configure Abp and Dependency Injection
return services.AddAbp(//Configure Log4Net logging
options => options.IocManager.IocContainer.AddFacility(
f=> f.UseAbpLog4Net().WithConfig("log4net.config")
)
);
}public voidConfigure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.UseAbp(options=> { options.UseAbpRequestLocalization = false; }); //Initializes ABP framework.
app.UseCors(_defaultCorsPolicyName);//Enable CORS!
app.Use(async (context, next) => { await next(); if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !context.Request.Path.Value.StartsWith("/api/services", StringComparison.InvariantCultureIgnoreCase)) { context.Request.Path = "/index.html"; awaitnext(); } });
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAbpRequestLocalization();
app.UseEndpoints(endpoints=>{
endpoints.MapHub("/signalr");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
});//Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/swagger.json"; });//Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(options =>{//specifying the Swagger JSON endpoint.
options.SwaggerEndpoint($"/swagger/{_apiVersion}/swagger.json", $"OPS02 API {_apiVersion}");
options.IndexStream= () =>Assembly.GetExecutingAssembly()
.GetManifestResourceStream("OPS02.Web.Host.wwwroot.swagger.ui.index.html");
options.DisplayRequestDuration();//Controls the display of the request duration (in milliseconds) for "Try it out" requests.
}); //URL: /swagger
app.UseSpa(spa=>{
spa.Options.SourcePath= "./";if (true)
{
spa.UseAngularCliServer(npmScript:"start");
}
});
}
}
}