常用词汇:
1.GUID: 默认值设置 有序:NEWSEQUENTIALID() 无序:NEWID()
2.获取json数据的方法: IConfiguration["Key:ChidKey"]
常用代码:
1.1. 根据数据库生成实体类和数据连接,放在实体类所在项目生成,几乎不用改动,更方便.
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Test
1.2. startup数据库连接配置与appsettings.json配置
public StartupDevelopment(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyContext")));
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "ConnectionStrings": { "MyContext": "Server=.;Database=BlogDemo;Trusted_Connection=True;MultipleActiveResultSets=true" } }
1.3. HTTPS HSTS
services.AddHttpsRedirection(options => { options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect; options.HttpsPort = 5001; }); services.AddHsts(options => { options.Preload = true; options.IncludeSubDomains = true; options.MaxAge = TimeSpan.FromDays(60); options.ExcludedHosts.Add("example.com"); options.ExcludedHosts.Add("www.example.com"); });
1.4. UseStartup<Startup>(); 使用基于环境的类
.UseStartup(typeof(StartupDevelopment).GetTypeInfo().Assembly.FullName);
1.5.1 表为空填写默认数据,在program.cs修改如下
// CreateWebHostBuilder(args).Build().Run(); 将词句注释掉, var host= CreateWebHostBuilder(args).Build(); using (var scope=host.Services.CreateScope()) { var services = scope.ServiceProvider; var loggerFactory = services.GetRequiredService<ILoggerFactory>(); try { var myContext = services.GetRequiredService<MyContext>(); MyContextSeed.SeedAsync(myContext, loggerFactory).Wait(); } catch (Exception e) { var logger = loggerFactory.CreateLogger<Program>(); logger.LogError(e,"填写默认数据失败"); } } host.Run();
1.5.2 数据表为
namespace BlogDemo.Infrastructure.Database { public class MyContextSeed { public static async Task SeedAsync(MyContext myContext, ILoggerFactory loggerFactory, int retry = 0) { int retryForAvailability = retry; try { // TODO: Only run this if using a real database // myContext.Database.Migrate(); if (!myContext.Posts.Any()) { myContext.Posts.AddRange( new List<Post>{ new Post{ Title = "Post Title 1", Body = "Post Body 1", Author = "Dave", LastModified = DateTime.Now }, new Post{ Title = "Post Title 2", Body = "Post Body 2", Author = "Dave", LastModified = DateTime.Now }, new Post{ Title = "Post Title 3", Body = "Post Body 3", Author = "Dave", LastModified = DateTime.Now } } ); await myContext.SaveChangesAsync(); } } catch (Exception ex) { if (retryForAvailability < 10) { retryForAvailability++; var logger = loggerFactory.CreateLogger<MyContextSeed>(); logger.LogError(ex.Message); await SeedAsync(myContext, loggerFactory, retryForAvailability); } } } } }
1.6.1 Serilog,在program.cs的main方法添加
Log.Logger = new LoggerConfiguration()
// .MinimumLevel.Debug()
.MinimumLevel.Error()
// .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft", LogEventLevel.Error) .Enrich.FromLogContext() .WriteTo.Console() .WriteTo.File(Path.Combine("logs", @"log.txt"), rollingInterval: RollingInterval.Day) .CreateLogger();
1.7.映射
安装nuget :
AutoMapper
AutoMapper.Extensions.Microsoft.DependencyInjection
创建Extensions/MappingProfile.cs 继承于Profile (using AutoMapper;)
然后在构造函数里添加映射
public class MappingProfile:Profile { public MappingProfile() { CreateMap<Post, PostResource>()
.ForMember(dest=>dest.UpdaDateTime,opt=>opt.MapFrom(src=>src.LastModified)); CreateMap<PostResource, Post>(); } }
在控制器里使用
var postResources = _mapper.Map<IEnumerable<Post>, IEnumerable<PostResource>>(posts);
1.8 FluentValidation
1.安装 FluentValidation
2.建立PostResourceValidator.添加继承,添加构造函数
public class PostResourceValidator:AbstractValidator<PostResource> { public PostResourceValidator() { RuleFor(x => x.Author) .NotNull() .WithName("作者") .WithMessage("{PropertyName}是必须填写的") .MaximumLength(50) .WithMessage("{PropertyName}的最大长度是{MaxLength}"); } }
3.在Startup.cs 注册
services.AddTransient<IValidator<PostResource>, PostResourceValidator>();
2.1 翻页 过滤 排序
2.1.1翻页: Query String http://localhost:5000/api/posts?pageIndex=2&pageSize=10&orderBy=Id
1.建立 QueryParameters.cs 数据分页方法类 包含.pageIndex, pageSize, orderBy 等分页参数
2.建立PostParameters.cs post专用的分页类,继承自QueryParameters.cs 即可.(无特殊条件可以不用写其他内容,继承功能够用即可)
3.1把PostParameters 传给PostController.cs 的[HttpGet] 如下:
public async Task<IActionResult> Get(PostParameters postParameters)
3.2把postParameters传给PostController.cs具体的实现方法
原来: var postList = await _postRepository.GetAllPostAsync(); 改为: var postList = await _postRepository.GetAllPostAsync(postParameters);
3.3给接口添加参数
同时修改接口 原来: Task<PaginatedList<Post>> GetAllPostAsync(); 改为: Task<PaginatedList<Post>> GetAllPostAsync(PostParameters postParameters);
3.4在实现类添加参数 PostParameters postParameters,同时原来的列表方法修改下如下
原来为直接列出列表数据. return await _myContext.Post.ToListAsync(); 改为: 1.按Id排序 var query = _myContext.Post.OrderBy(x => x.Id); 2.数据分页 var data = await query.Skip(postParameters.PageIndex * postParameters.PageSize)
.Take(postParameters.PageSize).ToListAsync();
2.1 REST
2.2 HTTP GET
2.2 状态码
200系列 成功
400系列 客户端引起的错误
500系列 服务器端引起的错误