.NET经销商实战(四)——automapper的配置,jwt授权鉴权,商品信息获取及swagger鉴权集成
1.在DealerPlatform.Service项目中添加引用两个包,automapper的包
AutoMapper
,AutoMapper.Extensions.Microsoft.DependencyInjection
2.添加一个新的类:DealerPlatformProfile,代码如下:
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using DealerPlatform.Domain.Models;
using DealerPlatform.Service.ProductApp.Dto;
namespace DealerPlatform.Service
{
///
/// 模型转换映射
///
public class DealerPlatformProfile : Profile
{
public DealerPlatformProfile()
{
//.ForMember(dest => dest.Id, opt => opt.Ignore())
CreateMap().ReverseMap();
CreateMap().ReverseMap();
CreateMap().ReverseMap();
CreateMap().ReverseMap();
}
}
}
添加完映射之后,下面就要注入automapper服务了
3.在program中添加builder.Services.AddAutoMapper(typeof(DealerPlatformProfile));
这样就可以了,program的注入顺序会在下面放出完整代码,耐心点,继续往下学
4.下面这个是Service类库的结构,如下,大家自行创建商品productservice类
5.为了让IProductService能够被我们之前写过的注入服务检测到,所以我们需要在IProductService中继承IocTag
代码如下:
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DealerPlatform.Domain;
using DealerPlatform.Service.ProductApp.Dto;
namespace DealerPlatform.Service.ProductApp
{
public interface IProductService : IocTag
{
Task> GetProductDto(string sort = null, int pageIndex = 1, int pageSize = 30);
}
}
构造函数注入及继承接口等都在ProductService里,在下面
6.ProductService.Photo代码如下(主要为了获取商品图片)
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DealerPlatform.Domain.Models;
namespace DealerPlatform.Service.ProductApp
{
public partial class ProductService
{
///
/// 获取商品的图片
///
///
///
public async Task> GetProductPhotosByProductNo(params string[] productNos)
{
var data = await ProductPhotoRepo.GetListAsync(s => productNos.Contains(s.ProductNo));
return data;
}
}
}
7.ProductService.Sales代码如下,获取商品的销售信息
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DealerPlatform.Domain.Models;
namespace DealerPlatform.Service.ProductApp
{
public partial class ProductService
{
///
/// 获取商品的销售量
///
///
///
public async Task> GetProductSalesByProductNo(params string[] productNos)
{
var data = await ProductSaleRepo.GetListAsync(s => productNos.Contains(s.ProductNo));
return data;
}
}
}
8.在ProductService中写入如下代码,注入服务及继承接口等都在这里
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain.Models;
using DealerPlatform.Service.ProductApp.Dto;
namespace DealerPlatform.Service.ProductApp
{
public partial class ProductService : IProductService
{
public ProductService(
IRepository productRepo,
IRepository productSaleRepo,
IRepository productSaleAreaDiffRepo,
IRepository productPhotoRepo,
IMapper mapper)
{
ProductRepo = productRepo;
ProductSaleRepo = productSaleRepo;
ProductSaleAreaDiffRepo = productSaleAreaDiffRepo;
ProductPhotoRepo = productPhotoRepo;
Mapper = mapper;
}
public IRepository ProductRepo { get; }
public IRepository ProductSaleRepo { get; }
public IRepository ProductSaleAreaDiffRepo { get; }
public IRepository ProductPhotoRepo { get; }
public IMapper Mapper { get; }
///
/// 获取商品数据
///
///
public async Task> GetProductDto(string sort = null, int pageIndex = 1, int pageSize = 30)
{
sort ??= "ProductName";
int skipNum = (pageIndex - 1) * pageSize;
//获取商品主档信息
var products = (await ProductRepo.GetListAsync()).OrderBy(s => s.GetType().Name == sort).Skip(skipNum).Take(pageSize);
var dtos = Mapper.Map>(products);
var productPhotos = await GetProductPhotosByProductNo(dtos.Select(s => s.ProductNo).ToArray());
var productSales = await GetProductSalesByProductNo(dtos.Select(s => s.ProductNo).ToArray());
dtos.ForEach(s =>
{
s.ProductPhoto = productPhotos.FirstOrDefault(c => c.ProductNo == s.ProductNo);
s.ProductSale = productSales.FirstOrDefault(c => c.ProductNo == s.ProductNo);
});
//根据productId取到属性
return dtos;
}
}
}
到这里我们就可以成功获取商品的信息了,下面我们开始jwt授权鉴权,这里我只提供简易版(配置鉴权方案),想学习鉴权策略可以看我另一篇文章,如需更多完整的可以移步看我另一篇文章
9.jwt鉴权方案
在program中加入如下代码(想知道完整的代码请继续往下看,说完swagger集成,我就放出完整代码):
点击查看代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
//是否是https 默认true
opt.RequireHttpsMetadata = false;
opt.SaveToken = true;
opt.TokenValidationParameters = new()
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Security)),
ValidIssuer = token.Issuer,
ValidAudience = token.Audience
};
opt.Events = new JwtBearerEvents
{
OnChallenge = context =>
{
//此处终止代码
context.HandleResponse();
var res = "{\"code\":401,\"err\":\"无权限\"}";
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.Response.WriteAsync(res);
return Task.FromResult(0);
}
};
});
10.swagger集成
点击查看代码
builder.Services.AddSwaggerGen(c =>
{
//添加安全定义
c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
{
Description = "格式:Bearer {token}",
Name = "Authorization",//默认的参数名
In = ParameterLocation.Header,//放于请求头中
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = JwtBearerDefaults.AuthenticationScheme
});
//添加安全要求
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = JwtBearerDefaults.AuthenticationScheme }
},
new List()
}
});
});
11.在program中使用鉴权方案
app.UseAuthentication();
既然已经添加了授权鉴权方案及swagger集成,我们现在可以启动一下我们的项目,可以看到swagger上已经有了小锁子,就是需要你的token就行鉴权
这时,我们没有为控制器上或者方法上添加鉴权方案,需要添加一下,这里有坑,注意!
12.在控制器上添加鉴权方案
按下f12进入Authorize特性中,发现如下:
program完整代码:
点击查看代码
using System.Net;
using System.Text;
using DealerPlatform.Common.JwtTokenModule.Models;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain.Models;
using DealerPlatform.Extensions;
using DealerPlatform.Service;
using DealerPlatform.Service.CustomerApp;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var configuration = builder.Configuration;
//获取jwt配置文件
builder.Services.AddControllers();
// builder.Services.AddTransient(typeof(IRepository<>), typeof(Repository<>));
// builder.Services.AddTransient();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
// builder.Services.AddEndpointsApiExplorer();
builder.Services.AddCors(c => c.AddPolicy("any", p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));
var token = configuration.GetSection("Jwt").Get();
//
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
//是否是https 默认true
opt.RequireHttpsMetadata = false;
opt.SaveToken = true;
opt.TokenValidationParameters = new()
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Security)),
ValidIssuer = token.Issuer,
ValidAudience = token.Audience
};
opt.Events = new JwtBearerEvents
{
OnChallenge = context =>
{
//此处终止代码
context.HandleResponse();
var res = "{\"code\":401,\"err\":\"无权限\"}";
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.Response.WriteAsync(res);
return Task.FromResult(0);
}
};
});
builder.Services.AddDbContext(opt =>
opt.UseSqlServer(configuration.GetConnectionString("Default")));
builder.Services.AddAutoMapper(typeof(DealerPlatformProfile));
//反射注册Repository
builder.Services.RepositoryRegister();
builder.Services.ServiceRegister();
builder.Services.AddSwaggerGen(c =>
{
//添加安全定义
c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
{
Description = "格式:Bearer {token}",
Name = "Authorization",//默认的参数名
In = ParameterLocation.Header,//放于请求头中
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = JwtBearerDefaults.AuthenticationScheme
});
//添加安全要求
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = JwtBearerDefaults.AuthenticationScheme }
},
new List()
}
});
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// app.UseHttpsRedirection();
app.UseCors("any");
app.MapControllers();
app.Run();