Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache
Microsoft.Extensions.Caching.Redis.RedisCache
Microsoft.Extensions.Caching.SqlServer.SqlServerCache
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache
都继承了IDistributedCache,所以它们公用一套set ,get... 方法,可灵活按需切换
使用MemoryDistributedCache时则
services.AddDistributedMemoryCache();
使用StackExchangeRedis时则
services.RemoveAll(typeof(IDistributedCache));//移除其他所有IDistributedCache相关服务
services.AddStackExchangeRedisCache(opts =>
{
opts.Configuration = config;
opts.InstanceName = name;
});
重写模块,下载地址:URL Rewrite : The Official Microsoft IIS Site
代理模块,下载地址:Application Request Routing : The Official Microsoft IIS Site
下载之后直接点击文件运行下一步即可,安装好之后,IIS中就会多出2个功能模块:URL重写,Application Request Routing
3. 将打包好的vue发布文件,复制到服务器,IIS新建网站
4. IIS头节点,打开Application Request Routing,然后在页面右侧找到Server Proxy Settings按钮,点击进入设置;把Enable proxy前面打上勾,然后在页面右侧点击应用即可
5. 选中自己创建好的OMS的前端网站,双击“URL重写”功能,进行相关重写配置,这里的配置其实最终会在网站的根节点创建一个Web.config文件
public class ParentEntity
{
public int Id { get;set;}
public virtual ICollection Children { get; set; }
....
}
public class ChildrenEntity
{
public int Id { get;set;}
public int ParentId { get;set;}
public virtual ParentEntity Parent { get; set; }
....
}
//关联关系配置
builder.HasMany(m => m.ChildrenEntity).WithOne(a => a.ParentEntity).HasForeignKey(s => s.ParentId );
//执行Children.Remove(item),会实删这一条数据
2. 弱关联-外键可空
public class ParentEntity
{
public int Id { get;set;}
public virtual ICollection Children { get; set; }
....
}
public class ChildrenEntity
{
public int Id { get;set;}
public virtual ParentEntity Parent { get; set; }//会生成可空的ParentId
....
}
//执行Children.Remove(item),不会实删这一条数据,会将这一条数据的 ParentId 置为空
//要想实删这一条数据,只能执行EF的Delete删除方法,手动删除
1. Vue.NetCore: 框架采用dotnetcore+vue+elementUI前后端分离;框架提供vue2、vue3版本 ;不一样的快速开发框架.http://www.volcore.xyz/
2. osharp: OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现
public class UpperCamelCaseNamingStrategy : NamingStrategy
{
protected override string ResolvePropertyName(string name)
{
if (char.IsLower(name,0))
{
return string.Concat(name[0].ToString().ToUpper(), name.AsSpan(1));
}
return name;
}
}
new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver() {
NamingStrategy = new UpperCamelCaseNamingStrategy()
}
}
8. Core AuthorizationFilter
public class ClaimAuthorizeAttribute : IAuthorizationFilter
{
private const string JwtClaimName = "name";
private const string JwtClaimFullName = "full_name";
private const string JwtClaimEmail = "email";
private AuthorizationFilterContext context_;
public void OnAuthorization(AuthorizationFilterContext context)
{
context_ = context;
var res = context.HttpContext.AuthenticateAsync().Result;
if (!res.Succeeded && !HasAllowAnonymous())//no token and no AllowAnonymous
{
context.Result = new JsonResult(new { Message = res?.Failure?.Message ?? "Unauthorized." });
return;
}
var jwtHandler = new JwtSecurityTokenHandler();
var tokenHeader = context_.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
var jwtToken = jwtHandler.ReadJwtToken(tokenHeader);
var name = jwtToken.Claims.FirstOrDefault(x => x.Type == JwtClaimName)?.Value;
//var url = context.HttpContext.Request.Path.Value;
//var heads = context.HttpContext.Request.Headers;
//Microsoft.AspNetCore.Mvc.ObjectResult(res?.Failure?.Message) { StatusCode = 401 };
//context.Result = new Microsoft.AspNetCore.Mvc.StatusCodeResult(401);
}
private bool HasAllowAnonymous()
{
var filters_isAm = context_.Filters.Any(i => i is IAllowAnonymousFilter);
if (filters_isAm)
{
return true;
}
var endpoint = context_.HttpContext.GetEndpoint();
if (endpoint?.Metadata?.GetMetadata() != null)
{
return true;
}
return false;
}
}
9. Core ExceptionFilterAttribute
//IExceptionFilter 若是继承它就不能override
public class ExceptionAttribute: ExceptionFilterAttribute
{
public bool IsDefaultCanelCase { get; set; } = true;
public override void OnException(ExceptionContext context)
{
var retData = new
{
Message = context.Exception.Message,
};
var jsonResult = new JsonResult(retData, new JsonSerializerSettings
{
ContractResolver = IsDefaultCanelCase ? new DefaultContractResolver() : new CamelCasePropertyNamesContractResolver()
});
context.HttpContext.Response.StatusCode = 500;
context.ExceptionHandled = true;
context.Result = jsonResult;
}
}
10. Core Mappings 使用模式之一
CreateMappings全部写在Model里,以接口实现的形式CreateMappings:
namespace WebApplication3.Models
{
public interface IHaveMapping
{
void CreateMappings(IMapperConfigurationExpression configuration);
}
}
namespace WebApplication3.Models
{
public class TestModel: IHaveMapping
{
public string Id { get; set; }
public string AssetId { get; set; }
public int FilterNum { get; set; }
public string FilterSize { get; set; }
public string UserId { get; set; }
public void CreateMappings(IMapperConfigurationExpression configuration)
{
configuration.CreateMap();
configuration.CreateMap()
.ForMember(dest => dest.UserId, source => source.MapFrom(s => s.CreateUserId));
}
}
}
Mappings stratup 注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
//services.AddAutoMapper11();
services.AddAutoMapper(mapperConfigurationExpression =>
{
Type t_1 = typeof(IHaveMapping);
//获取所有实现IHaveMapping接口的类的类型
Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t1 => t1.GetInterfaces().Contains(t_1))).ToArray();
foreach (var t in types)
{
object o = Activator.CreateInstance(t);//创建该类型的对象实例
var method = t.GetMethod("CreateMappings");//反射获取方法(实例方法)
method.Invoke(o, new object[] { mapperConfigurationExpression });//调用实例方法
}
});
}
使用:
public IActionResult Index()
{
var entity = new TestEntity() { Id = "12", AssetId = "10", FilterNum = 1, FilterSize = "120",CreateUserId = "4554" };
var dto = _iMapper.Map(entity);
return View();
}
11. ActionFilter的试用
全局Filter, 在filter中使用注入service:
public class ExampleActionFilter : IAsyncActionFilter
{
private readonly IMemoryCache _memoryCache;
public ExampleActionFilter(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
//获取当前请求Action是否有某个属性
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var myAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(MyAttribute), false).Cast().FirstOrDefault();
}
}
//Starup注入
services.Configure(options =>
{
options.Filters.Add();
});
局部Filter,即继承Attribute,可以打在Action上给某个action使用
public class ExampleActionFilter : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var svc = context.HttpContext.RequestServices;
var cacheService = svc.GetService();
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var myAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(MyAttribute), false).Cast().FirstOrDefault();
await next();
}
}