图片上传是很常见的功能,里面有些固定的操作也可以沉淀下来。

本文记录使用Abp vNext做图片上传的姿势。

本文的技术核心与Abp无关,Abp只是手段!

目标

  1. 上传图片----->预览图片----->确定保存
  2. 支持集群部署

实现思路:

① 上传图片要使用WebAPI特定媒体类型:multipart/form-data;

② 因为要做图片预览,故在上传时利用AbpCache做一个临时缓存,返回图片Id

③ 前端利用FileReader渲染预览图;

④ [确定]: 发起持久化WebAPI(利用第②步返回的图片Id)

为什么强调支持集群部署?

就这个功能而言,[上传预览]和[确定保存]是两次Http WebAPI请求。

如果服务端使用的是Redis等进程外缓存: 那这正好是一个Stateless应用功能,集群环境次功能无惧!

如果服务端使用的是进程内缓存:在集群环境,前后两次请求有可能打到不同的App服务,后置的[确定保存]WebAPI因此可能报错, 此处需要做 [会话亲和性] Session affinity

实践

利用Abp做图片上传

IFormFile能力如下红框:

下面将图片二进制流转化为 base64字符串,注入Abp缓存组件IDistributedCache<string>

缓存图片字符串1小时。

[上传预览], [确定保存]的API完整代码如下:

/// <summary>
/// 上传预览, 返回待上传的图片id,Content-Type:multipart/form-data
/// </summary>
/// <returns></returns>
[Consumes("multipart/form-data")]
[Route("upload/preview")]
[ProducesResponseType(typeof(Guid),200)]
[HttpPost]
public async Task<Guid> UploadPicPreviewAsync(IFormFile uploadedFile)
{
var formFileName = uploadedFile.FileName;
if (!new[] { ".png", ".jpg", ".bmp" }.Any((item) => formFileName.EndsWith(item)))
{
throw new AbpValidationException("您上传的文件格式必须为png、jpg、bmp中的一种");
}
byte[] bytes;
using (var bodyStream = uploadedFile.OpenReadStream())
{
using (var m = new MemoryStream())
{
await bodyStream.CopyToAsync(m);
bytes = m.ToArray();
}
}
string base64 = Convert.ToBase64String(bytes);
var bgId = Guid.NewGuid();
_cache.Set($"{CurrentUser.TenantId}:bg:{bgId}", base64, new DistributedCacheEntryOptions { SlidingExpiration = new TimeSpan(1, 0, 0) });
return bgId;
} /// <summary>
/// 保存图片,要使用到前置API的预览图片id
/// </summary>
/// <param name="createPictureInput"></param>
/// <returns></returns>
[Route("upload/")]
[HttpPost]
public async Task<bool> UploadPicAsync([FromBody] CreatePictureInput createPictureInput)
{
var based64 = await _cache.GetAsync($"{CurrentUser.TenantId}:bg:{createPictureInput.PreviewPicId}");
if (string.IsNullOrEmpty(based64))
throw new AbpException("Cache Hotmap Picture do not find"); var model = ObjectMapper.Map<CreatePictureInput, Picture>(createPictureInput);
model.ProfileId = CurrentUser.TenantId;
model.BlobStorage = Convert.FromBase64String(based64);
return await _pictures.InsertAsync(model)!= null;
}

Default implementation of the IDistributedCache interface is the MemoryDistributedCache which works in-memory.

The Distributed Memory Cache (AddDistributedMemoryCache) is a framework-provided implementation of IDistributedCache that stores items in memory. The Distributed Memory Cache isn't an actual distributed cache. Cached items are stored by the app instance on the server where the app is running.

以上两段文字来自 Abp和Asp.NETCore官方文档:

  1. Abp默认的IDistributedCache实现是分布式内存缓存;
  2. ASP.NETCore 分布式内存缓存是框架内置的,是一个假的分布式缓存,实际是单纯的内存缓存。

在没有使用真实分布式缓存的情况下, 需要对前后两个API配置会话亲和性。

会话亲和性

下面从nginx、Azure、k8s ingress 三角度配置[会话亲和性],(全站生效)

会话亲和性的实现原理,是在接受客户端首次请求时响应某个cookie,服务器会认定使用同一个cookie的请求为一个会话。

1. nginx

属于nginx负载均衡的范畴:https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

示例如下:

upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
2. Azure App Service

Azure pp Service是Azure云平台提供的App托管服务,具备多实例自动缩放的能力,

其有关会话亲和性的配置如图:

3. K8S nginx-ingress

注解nginx.ingress.kubernetes.io/affinity在入口的所有上游中启用和设置亲和性类型。

这样,请求将总是被定向到相同的上游服务器。

https://kubernetes.github.io/ingress-nginx/examples/affinity/cookie/

That's All

本文以常见的图片上传功能为例,实战演练了Abp的缓存和持久化能力;

引申出对有状态应用配置会话亲和性,部署方式要结合业务功能。

希望对大家有所帮助!

Abp小试牛刀之 图片上传的更多相关文章

  1. Asp.Net Mvc 使用WebUploader 多图片上传

    来博客园有一个月了,哈哈.在这里学到了很多东西.今天也来试着分享一下学到的东西.希望能和大家做朋友共同进步. 最近由于项目需要上传多张图片,对于我这只菜鸟来说,以前上传图片都是直接拖得控件啊,而且还是 ...

  2. 06.LoT.UI 前后台通用框架分解系列之——浮夸的图片上传

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...

  3. JS图片上传预览插件制作(兼容到IE6)

    其实,图片预览功能非常地常见.很意外,之前遇到上传图片的时候都不需要预览,也一直没有去实现过.现在手上的项目又需要有图片预览功能,所以就动手做了一个小插件.在此分享一下思路. 一.实现图片预览的一些方 ...

  4. HTML5笔记:跨域通讯、多线程、本地存储和多图片上传技术

    最近做项目在前端我使用了很多新技术,这些技术有bootstrap.angularjs,不过最让我兴奋的还是使用了HTML5的技术,今天我想总结一些HTML5的技术,好记性不如烂笔头,写写文章可以很好的 ...

  5. 对百度的UEditor多图片上传的一些补充

    我已经写了一篇文章关于百度的UEditor提取多图片上传模块.如果还没有看过,请点击以下链接查看 http://www.cnblogs.com/luke1006/p/3719029.html 出差了两 ...

  6. 使用localResizeIMG3+WebAPI实现手机端图片上传

    前言 惯例~惯例~昨天发表的使用OWIN作为WebAPI的宿主..嗯..有很多人问..是不是缺少了什么 - - 好吧,如果你要把OWIN寄宿在其他的地方...代码如下: namespace Conso ...

  7. TinyMCE的使用(包括汉化及本地图片上传功能)

    TinyMCE我就不多介绍了,这是下载地址:https://www.tinymce.com/download/ 下载下来是英文版,要汉化也很简单.首先去网上随便下载个汉化包,然后把汉化包解压后的lan ...

  8. 包含修改字体,图片上传等功能的文本输入框-Bootstrap

    通过jQuery Bootstrap小插件,框任何一个div转换变成一个富文本编辑框,主要特色: 在Mac和window平台下自动针对常用操作绑定热键 可以拖拽插入图片,支持图片上传(也可以获取移动设 ...

  9. PHP多图片上传实例demo

    upload.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

随机推荐

  1. Appium上下文和H5测试(二)

    坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:oschina.云+社区.知乎等各大平台都有. 文章总览图 一.往期回顾 loc='new UiSelector().text("全程班&q ...

  2. 区块链V1版本实现之二

    部分程序代码(生成并调用hash代码): 1 //创建区块,对Block的每一个字段填充数据 2 func NewBlock(data string, prevBlockHash []byte) *B ...

  3. react高阶组件的一些运用

    今天学习了react高阶组件,刚接触react学习起来还是比较困难,和大家分享一下今天学习的知识吧,另外缺少的地方欢迎补充哈哈 高阶组件(Higher Order Components,简称:HOC) ...

  4. Docker实战 | 第二篇:IDEA集成Docker插件实现一键自动打包部署微服务项目,一劳永逸的技术手段值得一试

    一. 前言 大家在自己玩微服务项目的时候,动辄十几个服务,每次修改逐一部署繁琐不说也会浪费越来越多时间,所以本篇整理通过一次性配置实现一键部署微服务,实现真正所谓的一劳永逸. 二. 配置服务器 1. ...

  5. day6(短信验证接口)

    1.注册容联云账号 1.1注册账号 https://www.yuntongxun.com/user/login  1.2登录即可看到开发者账号信息 1.3 添加测试账号 2.使用容联云发送代码测试 ' ...

  6. 详解Hadoop3.x新特性功能-HDFS纠删码

    文章首发于微信公众号:五分钟学大数据 EC介绍 ​Erasure Coding 简称EC,中文名:纠删码 EC(纠删码)是一种编码技术,在HDFS之前,这种编码技术在廉价磁盘冗余阵列(RAID)中应用 ...

  7. Codeforces Round 665 (div2)

    2020.8.22 装修完了我的博客,喜欢这个造型,挂上友链就更好了 昨天cf就是一个彻头彻尾的悲剧,本来能上蓝,结果因为在A题耽误时间过多导致掉了30分,不过没关系,这算是一个小波动吧,影响不了什么 ...

  8. python之Bug之字符串拼接bug

    \r\n拼接Bug 环境: python3.4.pycharm2017 偶然的学习中遇到了一个问题,百思不得姐,什么问题呢,大家输入太快了,难免有失误就如下面的代码 #构造响应数据 response_ ...

  9. Python中sort、sorted的cmp参数废弃之后使用cmp_to_key实现类似功能

    Python2.1以前的排序比较方法只提供一个cmp比较函数参数,没有__lt__等6个富比较方法, Python 2.1引入了富比较方法,Python3.4之后作废了cmp参数.相应地从Python ...

  10. flask中SQLAlchemy学习

    ------------------------------------2019-08-22 17:53:54更新------------------------------ SQLALchemy实在 ...