自从使用Asp.net Core2.0 以来,不停摸索,查阅资料,这方面的资料是真的少,因此,在前人的基础上,摸索出了Asp.net Core2.0 缓存 MemoryCache 和 Redis的用法,并实现了简单的封装

那么,先给出几个参考资料吧

关于两种缓存:https://www.cnblogs.com/yuangang/p/5800113.html

关于redis持久化:https://blog.csdn.net/u010785685/article/details/52366977

两个nuget包,不用多说

接下来,贴出代码

首先在startup,我读取了appstting.json的数据,作为redis的配置

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Application.Common;
using Application.Common.CommonObject;
using Application.CoreWork;
using Application.DAL;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; namespace Application.web
{
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.
public void ConfigureServices(IServiceCollection services)
{
Connection.MySqlConnection = Configuration.GetConnectionString("MySqlConnection");
Connection.SqlConnection = Configuration.GetConnectionString("SqlConnection");
RedisConfig.Connection = Configuration.GetSection("RedisConfig")["Connection"];
RedisConfig.DefaultDatabase =Convert.ToInt32( Configuration.GetSection("RedisConfig")["DefaultDatabase"]);
RedisConfig.InstanceName = Configuration.GetSection("RedisConfig")["InstanceName"];
CommonManager.CacheObj.GetMessage<RedisCacheHelper>();
services.AddMvc();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

再贴上配置

"RedisConfig": {
"Connection": "127.0.0.1:6379",
"DefaultDatabase": 0,
"InstanceName": "Redis1"
},

  

用来放配置信息的静态类

using System;
using System.Collections.Generic;
using System.Text; namespace Application.Common
{
public static class RedisConfig
{
public static string configname { get; set; }
public static string Connection { get; set; }
public static int DefaultDatabase { get; set; }
public static string InstanceName { get; set; }
}
}

然后ICacheHelper.cs,这个类是两种缓存通用的接口,让使用更方便

using System;
using System.Collections.Generic;
using System.Net;
using System.Text; namespace Application.Common.CommonObject
{
public interface ICacheHelper
{
bool Exists(string key); T GetCache<T>(string key) where T : class; void SetCache(string key, object value); void SetCache(string key, object value, DateTimeOffset expiressAbsoulte);//设置绝对时间过期 void SetSlidingCache(string key, object value, TimeSpan t); //设置滑动过期, 因redis暂未找到自带的滑动过期类的API,暂无需实现该接口 void RemoveCache(string key); void KeyMigrate(string key, EndPoint endPoint,int database,int timeountseconds); void Dispose(); void GetMssages(); void Publish(string msg);
}
}

然后,实现接口,首先是MemoryCacheHelper

using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text; namespace Application.Common.CommonObject
{
public class MemoryCacheHelper : ICacheHelper
{
//public MemoryCacheHelper(/*MemoryCacheOptions options*/)//这里可以做成依赖注入,但没打算做成通用类库,所以直接把选项直接封在帮助类里边
//{
// //this._cache = new MemoryCache(options);
// //this._cache = new MemoryCache(new MemoryCacheOptions());
//}
//public MemoryCacheHelper(MemoryCacheOptions options)//这里可以做成依赖注入,但没打算做成通用类库,所以直接把选项直接封在帮助类里边
//{
// this._cache = new MemoryCache(options);
//} public static IMemoryCache _cache=new MemoryCache(new MemoryCacheOptions()); /// <summary>
/// 是否存在此缓存
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool Exists(string key)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
object v = null;
return _cache.TryGetValue<object>(key, out v);
}
/// <summary>
/// 取得缓存数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T GetCache<T>(string key) where T : class
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key)); T v = null;
_cache.TryGetValue<T>(key, out v); return v;
}
/// <summary>
/// 设置缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetCache(string key, object value)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value)); object v = null;
if (_cache.TryGetValue(key, out v))
_cache.Remove(key);
_cache.Set<object>(key, value);
}
/// <summary>
/// 设置缓存,绝对过期
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expirationMinute">间隔分钟</param>
/// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", 30);
public void SetCache(string key, object value, double expirationMinute)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value)); object v = null;
if (_cache.TryGetValue(key, out v))
_cache.Remove(key);
DateTime now = DateTime.Now;
TimeSpan ts = now.AddMinutes(expirationMinute) - DateTime.Now;
_cache.Set<object>(key, value, ts);
}
/// <summary>
/// 设置缓存,绝对过期
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expirationTime">DateTimeOffset 结束时间</param>
/// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", DateTimeOffset.Now.AddSeconds(30));
public void SetCache(string key, object value, DateTimeOffset expirationTime)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value)); object v = null;
if (_cache.TryGetValue(key, out v))
_cache.Remove(key); _cache.Set<object>(key, value, expirationTime);
}
/// <summary>
/// 设置缓存,相对过期时间
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="t"></param>
/// CommonManager.CacheObj.SaveSlidingCache<MemoryCacheHelper>("test", "MemoryCache works!",TimeSpan.FromSeconds(30));
public void SetSlidingCache(string key,object value,TimeSpan t)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value)); object v = null;
if (_cache.TryGetValue(key, out v))
_cache.Remove(key); _cache.Set(key, value, new MemoryCacheEntryOptions()
{
SlidingExpiration=t
});
}
/// <summary>
/// 移除缓存
/// </summary>
/// <param name="key"></param>
public void RemoveCache(string key)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key)); _cache.Remove(key);
} /// <summary>
/// 释放
/// </summary>
public void Dispose()
{
if (_cache != null)
_cache.Dispose();
GC.SuppressFinalize(this);
} public void KeyMigrate(string key, EndPoint endPoint, int database, int timeountseconds)
{
throw new NotImplementedException();
} public void GetMssages()
{
throw new NotImplementedException();
} public void Publish(string msg)
{
throw new NotImplementedException();
}
}
}

然后是RedisCacheHelper

using Microsoft.Extensions.Caching.Redis;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text; namespace Application.Common.CommonObject
{
public class RedisCacheHelper : ICacheHelper
{
public RedisCacheHelper(/*RedisCacheOptions options, int database = 0*/)//这里可以做成依赖注入,但没打算做成通用类库,所以直接把连接信息直接写在帮助类里
{
options = new RedisCacheOptions();
options.Configuration = "127.0.0.1:6379";//RedisConfig.Connection;
options.InstanceName = RedisConfig.InstanceName;
int database = RedisConfig.DefaultDatabase;
_connection = ConnectionMultiplexer.Connect(options.Configuration);
_cache = _connection.GetDatabase(database);
_instanceName = options.InstanceName;
_sub = _connection.GetSubscriber();
} public static RedisCacheOptions options;
public static IDatabase _cache; public static ConnectionMultiplexer _connection; public static string _instanceName; public static ISubscriber _sub; /// <summary>
/// 取得redis的Key名称
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private string GetKeyForRedis(string key)
{
return _instanceName + key;
}
/// <summary>
/// 判断当前Key是否存在数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool Exists(string key)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
return _cache.KeyExists(GetKeyForRedis(key));
} /// <summary>
/// 取得缓存数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T GetCache<T>(string key) where T : class
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
var value = _cache.StringGet(GetKeyForRedis(key));
if (!value.HasValue)
return default(T);
return JsonConvert.DeserializeObject<T>(value);
}
/// <summary>
/// 设置缓存数据
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetCache(string key, object value)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value)); if (Exists(GetKeyForRedis(key)))
RemoveCache(GetKeyForRedis(key)); _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value));
}
/// <summary>
/// 设置绝对过期时间
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiressAbsoulte"></param>
public void SetCache(string key, object value, DateTimeOffset expiressAbsoulte)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value)); if (Exists(GetKeyForRedis(key)))
RemoveCache(GetKeyForRedis(key));
TimeSpan t = expiressAbsoulte - DateTimeOffset.Now;
_cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), t);
}
/// <summary>
/// 设置相对过期时间
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expirationMinute"></param>
public void SetCache(string key, object value, double expirationMinute)
{
if (Exists(GetKeyForRedis(key)))
RemoveCache(GetKeyForRedis(key)); DateTime now = DateTime.Now;
TimeSpan ts = now.AddMinutes(expirationMinute) - now;
_cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), ts);
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="endPoint"></param>
/// <param name="database"></param>
/// <param name="timeountseconds"></param>
public void KeyMigrate(string key, EndPoint endPoint, int database, int timeountseconds) {
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
_cache.KeyMigrate(GetKeyForRedis(key), endPoint, database, timeountseconds);
}
/// <summary>
/// 移除redis
/// </summary>
/// <param name="key"></param>
public void RemoveCache(string key)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key)); _cache.KeyDelete(GetKeyForRedis(key));
} /// <summary>
/// 销毁连接
/// </summary>
public void Dispose()
{
if (_connection != null)
_connection.Dispose();
GC.SuppressFinalize(this);
} public void SetSlidingCache(string key, object value, TimeSpan t)
{
throw new NotImplementedException();
} public void GetMssages()
{
using (_connection = ConnectionMultiplexer.Connect(options.Configuration))
_sub.Subscribe("msg", (channel, message) =>
{
string result = message;
});
} public void Publish(string msg)
{
using (_connection=ConnectionMultiplexer.Connect(options.Configuration))
_sub.Publish("msg", msg);
}
}
}

然后是Cache.cs,用来实例化,此处用单例模式,保证项目使用的是一个缓存实例,博主吃过亏,由于redis实例过多,构造函数运行太多次,导致client连接数过大,内存不够跑,速度卡慢

using System;
using System.Collections.Generic;
using System.Text; namespace Application.Common.CommonObject
{
public sealed class Cache
{
internal Cache() { }
public static ICacheHelper cache;
/// <summary>
/// 判断缓存是否存在
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <returns></returns>
public bool Exists<CacheType>(string key) where CacheType : ICacheHelper, new()
{
if (cache!=null&& typeof(CacheType).Equals(cache.GetType()))
return cache.Exists(key);
else
{
cache = new CacheType();
return cache.Exists(key);
}
} /// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="T">转换的类</typeparam>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <returns>转换为T类型的值</returns>
public T GetCache<T,CacheType>(string key)
where T:class
where CacheType : ICacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
return cache.GetCache<T>(key);
else
{
cache = new CacheType();
return cache.GetCache<T>(key);
}
} /// <summary>
/// 保存缓存
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <param name="value">值</param>
public void Save<CacheType>(string key,object value) where CacheType : ICacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.SetCache(key, value);
else
{
cache = new CacheType();
cache.SetCache(key, value);
}
} /// <summary>
/// 保存缓存并设置绝对过期时间
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <param name="value">值</param>
/// <param name="expiressAbsoulte">绝对过期时间</param>
public void Save<CacheType>(string key, object value, DateTimeOffset expiressAbsoulte) where CacheType : ICacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.SetCache(key, value, expiressAbsoulte);
else
{
cache = new CacheType();
cache.SetCache(key, value, expiressAbsoulte);
}
} /// <summary>
/// 保存滑动缓存
/// </summary>
/// <typeparam name="CacheType">只能用memorycache,redis暂不实现</typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="t">间隔时间</param>
public void SaveSlidingCache<CacheType>(string key, object value,TimeSpan t) where CacheType : MemoryCacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.SetSlidingCache(key, value, t);
else
{
cache = new CacheType();
cache.SetSlidingCache(key, value, t);
}
} /// <summary>
/// 删除一个缓存
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">要删除的key</param>
public void Delete<CacheType>(string key)where CacheType : ICacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.RemoveCache(key);
else
{
cache = new CacheType();
cache.RemoveCache(key);
}
} /// <summary>
/// 释放
/// </summary>
/// <typeparam name="CacheType"></typeparam>
public void Dispose<CacheType>() where CacheType : ICacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.Dispose();
else
{
cache = new CacheType();
cache.Dispose();
}
} public void GetMessage<CacheType>() where CacheType:RedisCacheHelper,new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.GetMssages();
else
{
cache = new CacheType();
cache.GetMssages();
}
} public void Publish<CacheType>(string msg)where CacheType : RedisCacheHelper, new()
{
if (cache != null && typeof(CacheType).Equals(cache.GetType()))
cache.Publish(msg);
else
{
cache = new CacheType();
cache.Publish(msg);
}
}
}
}

接下来,CommonManager.cs,该类主要是为了作为一个静态类调用缓存,由于Cache.cs并非静态类,方便调用

using Application.Common.CommonObject;
using System;
using System.Collections.Generic;
using System.Text; namespace Application.Common
{
public class CommonManager
{
private static readonly object lockobj = new object();
private static volatile Cache _cache = null;
/// <summary>
/// Cache
/// </summary>
public static Cache CacheObj
{
get
{
if (_cache == null)
{
lock (lockobj)
{
if (_cache == null)
_cache = new Cache();
}
}
return _cache;
}
}
}
}

最后呢就是使用啦随便建的一个控制器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Application.Common;
using Application.Common.CommonObject;
using Application.CoreWork;
using Microsoft.AspNetCore.Mvc; namespace Application.web.Controllers
{
public class DefaultController : BaseController
{
public IActionResult Index()
{
for (int i = ; i < ; i++)
{
CommonManager.CacheObj.Save<RedisCacheHelper>("key" + i, "key" + i + " works!");
}
return View();
} public IActionResult GetStrin(int index)
{
string res = "已经过期了";
if (CommonManager.CacheObj.Exists<RedisCacheHelper>("key" + index))
{
res = CommonManager.CacheObj.GetCache<String, RedisCacheHelper>("key" + index);
}
return Json(new ExtJson { success = true, code = , msg = "成功", jsonresult = res });
} public IActionResult Publish(string msg)
{
try
{
CommonManager.CacheObj.Publish<RedisCacheHelper>(msg);
return Json(new ExtJson { success = true, code = , msg = "成功", jsonresult = msg });
}
catch
{
return Json(new ExtJson
{
success = true,
code = ,
msg = "失败",
jsonresult = msg
});
}
}
}
}

那么,有的朋友在json处可能会报错,自己封装下,或者用原来的json吧

如果有不懂的地方,可以在评论中提问,有更好的改进方式,也请联系我,共同进步,感谢阅读

2019-5-23更新

在实际运行过程中,发现大量用户请求,并且两种缓存混合使用时,redis和memory的单例会多次创建,导致redis连接数达到上限,下面贴出修改后的cache.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text; namespace Application.Common.CommonObject
{
public sealed class Cache
{
internal Cache() { }
public static ICacheHelper cache; public static RedisCacheHelper redis;
public static MemoryCacheHelper memory; public ICacheHelper Getcachehelper<CacheType>()
{
if (typeof(CacheType).Equals(typeof(RedisCacheHelper)))
{
if (redis == null)
{
redis = new RedisCacheHelper();
Process pc = Process.GetCurrentProcess();
CommonManager.TxtObj.Log4netError("进程ID:"+pc.Id+";redis为null,创建一个新的实例",typeof(Cache),null);
}
return redis;
}
else if (typeof(CacheType).Equals(typeof(MemoryCacheHelper)))
{
if (memory == null)
memory = new MemoryCacheHelper();
return memory;
}
else
return null;
}
/// <summary>
/// 判断缓存是否存在
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <returns></returns>
public bool Exists<CacheType>(string key) where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
return cache.Exists(key);
} /// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="T">转换的类</typeparam>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <returns>转换为T类型的值</returns>
public T GetCache<T, CacheType>(string key)
where T : class
where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
return cache.GetCache<T>(key);
} /// <summary>
/// 保存缓存
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <param name="value">值</param>
public void Save<CacheType>(string key, object value) where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.SetCache(key, value);
} /// <summary>
/// 保存缓存并设置绝对过期时间
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">键名</param>
/// <param name="value">值</param>
/// <param name="expiressAbsoulte">绝对过期时间</param>
public void Save<CacheType>(string key, object value, DateTimeOffset expiressAbsoulte) where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.SetCache(key, value, expiressAbsoulte);
} /// <summary>
/// 保存滑动缓存
/// </summary>
/// <typeparam name="CacheType">只能用memorycache,redis暂不实现</typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="t">间隔时间</param>
public void SaveSlidingCache<CacheType>(string key, object value, TimeSpan t) where CacheType : MemoryCacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.SetSlidingCache(key, value, t);
} /// <summary>
/// 删除一个缓存
/// </summary>
/// <typeparam name="CacheType">缓存类型</typeparam>
/// <param name="key">要删除的key</param>
public void Delete<CacheType>(string key) where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.RemoveCache(key);
} /// <summary>
/// 释放
/// </summary>
/// <typeparam name="CacheType"></typeparam>
public void Dispose<CacheType>() where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.Dispose();
}
public List<string> GetCacheKeys<CacheType>() where CacheType : ICacheHelper, new()
{
cache = Getcachehelper<CacheType>();
return cache.GetCacheKeys();
}
public void GetMessage<CacheType>() where CacheType : RedisCacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.GetMssages();
} public void Publish<CacheType>(string msg) where CacheType : RedisCacheHelper, new()
{
cache = Getcachehelper<CacheType>();
cache.Publish(msg);
}
}
}

  

Asp.net Core2.0 缓存 MemoryCache 和 Redis的更多相关文章

  1. Asp.net Core 缓存 MemoryCache 和 Redis

    Asp.net Core 缓存 MemoryCache 和 Redis 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 经过 N 久反复的尝试,翻阅了网上无数的资料,GitH ...

  2. 一步一步带你做WebApi迁移ASP.NET Core2.0

    随着ASP.NET Core 2.0发布之后,原先运行在Windows IIS中的ASP.NET WebApi站点,就可以跨平台运行在Linux中.我们有必要先说一下ASP.NET Core. ASP ...

  3. 【翻译】asp.net core2.0中的token认证

    原文地址:https://developer.okta.com/blog/2018/03/23/token-authentication-aspnetcore-complete-guide token ...

  4. 【转】Asp.Net Core2.0获取客户IP地址,及解决发布到Ubuntu服务器获取不到正确IP解决办法

    1.获取客户端IP地址实现方法(扩展类) using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; u ...

  5. [翻译]在asp.net core2.0 OpenID Connect Handler中丢失了声明(CLaims)?

    注:这是一篇翻译,来自这里.这篇文章讲述了在asp.net core2.0中使用openid connect handler的过程中解析不到你想要的claim时,你可以参考这篇文章. Missing ...

  6. Asp.Net Core2.0获取客户IP地址,及解决发布到Ubuntu服务器获取不到正确IP解决办法

    1.获取客户端IP地址实现方法(扩展类) using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; u ...

  7. VS2017创建一个 ASP.NET Core2.0 应用,并搭建 MVC 框架

    https://testerhome.com/topics/11747 1.使用最新版本的VS2017,并安装.NET Core2.0中相关开发工具   2.打开VS2017,点击文件-新建-项目,选 ...

  8. 在阿里云Windows Server 上部署ASP .NET CORE2.0项目

    近期使用ASP.NET Core2.0对博客进行了重写,在部署到服务器时遇到了一些问题,来记录一下留用. 配置环境 安装 .Net Framework3.5 在IIS管理器上直接开启,这里总是失败,上 ...

  9. 通过Mysql连接ASP.Net Core2.0(Code First模式)

    ASP.NET Core2.0连接Mysql,首先新建项目 选择Web应用程序 选择需要身份验证: 通过Nuget安装Mysql驱动,这里推荐>Pomelo.EntityFrameworkCor ...

随机推荐

  1. 随记PC-win7 64位系统网络连接状态一直转圈、等待状态的异常解决方案

    各位看官好~ 最近电脑也做了下升级,入手个士必得360G的SSD来玩玩,顺便也下个新系统,看看有什么区别,想想顺便升级下系统也是好的,就开始了装机,装系统的路程~~~~~~ 好了不说废话,直接进入主题 ...

  2. MySQL数据库操作类(PHP实现,支持连贯操作)

    <?php /** * Author: suvan * CreateTime: 2018/2/27 * description: 数据库操作类(仅对接MySQL数据库,主要利用MySQLi函数) ...

  3. JavaScript(第三十三天)【总结:封装基础前端框架】

    源码地址:https://github.com/whisper540/Base

  4. JavaScript(第二十四天)【事件对象】

    JavaScript事件的一个重要方面是它们拥有一些相对一致的特点,可以给你的开发提供更多的强大功能.最方便和强大的就是事件对象,他们可以帮你处理鼠标事件和键盘敲击方面的情况,此外还可以修改一般事件的 ...

  5. Maven+SSM框架搭建【spring+springmvc+mybatis】

    本案例用到:ssm[spring+springmvc+mybatis]框架 数据库:mysql (推荐使用mysql 或者 sqlserver  .oracle太大,一般大型项目才会用到) 开发工具: ...

  6. 微信APP简要分析

    Part1 走进微信APP 很明显,微信是很成功的APP. 微信 (WeChat) 是腾讯公司于2011年1月21日推出的一个为智能终端提供即时通讯服务的免费应用程序,现已是超过九亿人使用的手机应用. ...

  7. C语言第七次作业

    一.PTA实验作业 题目1:求整数序列中出现次数最多的数 1.本题PTA提交列表 2.设计思路 定义一个整型数组a[1001],i,j 为循环变量,N,定义数组b[1001]={0} 输入N for( ...

  8. 团队作业5-测试与发布(AIpha版本)

    对于已完成的项目我们进行了诸多测试,找到了少许bug,对着这些bug我们在改进的基础上提出了新的目标. 1,测试环境:个人笔记本.个人台式机.环境windows7.网络校园网加移动vpn,浏览器360 ...

  9. Linux kernel 的 sendfile 是如何提高性能的

    Linux kernel 的 sendfile 是如何提高性能的 现在流行的 web 服务器里面都提供 sendfile 选项用来提高服务器性能,那到底 sendfile 是什么,怎么影响性能的呢? ...

  10. JVM笔记7-内存分配与回收策略

    1.对象优先在Eden分配 大多数情况下,对象在新生代Eden区中分配.当Eden区中没有足够空间分配时,虚拟机将发起一次Minor GC.虚拟机提供了-XX:PrintGCDetails 这个收集器 ...