前言
最近项目中要做一些图片的存放功能,网上找了找WebApi的文件上传存放,用的挺多的是HttpPostedFileBase的方式,不过我希望是图片和数据都同时通过一个POST上传上来,所以这次我们改用的是MultipartFormDataStreamProvider的方式。
实现效果
代码实现
由于我这是在项目直接使用了,所以只把关键的东西介绍一下
通讯类介绍
返回类CResponse
请求类CRequest
数据表及对应类
数据表tVipMember_Pic
对应类CVipMemPic
///<summary>
///会员图片
///</summary>
[SugarTable("tVipMember_Pic")]
public partial class CVipMemberPic
{
public CVipMemberPic(){
}
/// <summary>
/// Desc:会员编码
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public string VipNO {get;set;}
/// <summary>
/// Desc:照片序号
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public int Photoidx {get;set;}
/// <summary>
/// Desc:照片类型
/// Default:
/// Nullable:True
/// </summary>
public string Phototype { get; set; }
/// <summary>
/// Desc:照片
/// Default:
/// Nullable:True
/// </summary>
public byte[] Photo {get;set;}
}
WebApi
定义会员图片Controller
上传会员图片Post
核心代码
/// <summary>
/// 上传图片
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[MsgRecordFilter]
[Route("Uploadfile")]
public async Task<CResponse<List<CVipMemberPic>>> Uploadfile()
{
CResponse<List<CVipMemberPic>> response = new CResponse<List<CVipMemberPic>>();
try
{
if (!Request.Content.IsMimeMultipartContent())
{
response.ResId = -1;
response.ResMsg = "通讯的数据有问题";
return response;
}
//指定要将文件存入的服务器物理位置
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
//删除生成30天以上的文件
DateTime date = DateTime.Today.AddDays(-30);
FileApi.DelFileFromDate(root, date);
//读取数据
await Request.Content.ReadAsMultipartAsync(provider);
//获取请求字符串
string json = provider.FormData["json"];
CRequest<string> req = JsonConvert.DeserializeObject<CRequest<string>>(json);
//校验签名
if (!TransSignApi.CheckRequestSignTs(req))
{
response.ResId = -1;
response.ResMsg = "通讯签名不正确!";
return response;
}
//获取图片序列号
int vipidx = 1;
List<CVipMemberPic> pics = new List<CVipMemberPic>();
foreach (MultipartFileData file in provider.FileData)
{
FileStream fs = null;
byte[] pReadByte = new byte[0];
try
{
fs = new FileStream(file.LocalFileName,
FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
//将文件指针设置到文件开
r.BaseStream.Seek(0, SeekOrigin.Begin);
pReadByte = r.ReadBytes((int)r.BaseStream.Length);
//获取新的会员图片
CVipMemberPic pic = new CVipMemberPic();
pic.VipNO = req.ReqData;
pic.Photoidx = vipidx;
pic.Phototype = file.Headers.ContentDisposition.FileName;
pic.Photo = pReadByte;
pics.Add(pic);
vipidx++;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (fs != null) fs.Close();
}
}
int count = VipMemberPicApi.SavePhoto(pics);
if (count > 0)
{
response.ResId = 1;
response.ResMsg = "成功上传" + count + "张图片";
response.ResData = pics;
}
else
{
response.ResId = -1;
response.ResMsg = "图片未保存成功!";
response.ResData = null;
}
}
catch (Exception ex)
{
response.ResId = -1;
response.ResMsg = ex.Message;
response.ResData = null;
}
return response;
}
}
下载会员图片Get
核心代码
/// <summary>
/// 获取会员图片
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
[Route("Downloadfile")]
public CResponse<List<CVipMemberPic>> GetVipPic(
[FromUri] CRequest<string> req)
{
CResponse<List<CVipMemberPic>> response = new CResponse<List<CVipMemberPic>>();
try
{
//校验签名
if (!TransSignApi.CheckRequestSignTs(req))
{
response.ResId = -1;
response.ResMsg = "通讯签名不正确!";
return response;
}
//获取会员
List<CVipMemberPic> pics = VipMemberPicApi.GetVipPic(req.ReqData);
if (pics == null)
{
response.ResId = -1;
response.ResMsg = "获取不到会员图片!";
response.ResData = null;
}
else
{
response.ResId = 1;
response.ResMsg = "获取到" + pics.Count + "会员图片!";
response.ResData = pics;
}
}
catch (Exception ex)
{
response.ResId = -1;
response.ResMsg = ex.Message;
response.ResData = null;
}
return response;
}
WinForm端调用
我们封装了一个Get和Post的调用类,这里我只把Get和Post上传的这块摘出来
WebapiHelper
Get方法
/// <summary>
/// Get请求指定的URL地址
/// </summary>
/// <typeparam name="T">返回的json转换成指定实体对象</typeparam>
/// <param name="url">URL地址</param>
/// <returns></returns>
public static T GetWebAPI<T>(string url) where T : class, new()
{
T result = default(T);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
string s = t.Result;
string jsonNamespace = DeserializeObject<T>(s).ToString();
result = DeserializeObject<T>(s);
}
}
return result;
}
POST上传数据及图片的方法
/// <summary>
/// Post请求指定的URL地址
/// </summary>
/// <typeparam name="T">返回的json转换成指定实体对象</typeparam>
/// <param name="url">URL地址</param>
/// <param name="postData">提交到Web的Json格式的数据:如:{"ErrCode":"FileErr"}</param>
/// <param name="filepath">文件地址</param>
/// <returns></returns>
public static T PostWebAPI<T>(string url, string postData, List<byte[]> byteses) where T : class, new()
{
T result = default(T);
HttpClientHandler httpHandler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
using (HttpClient httpClient = new HttpClient(httpHandler))
{
using (var multipart = new MultipartFormDataContent())
{
//加入Json数据
HttpContent dataContent = new StringContent(postData, Encoding.UTF8, "application/json");
dataContent.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment")
{
Name = "json"
};
multipart.Add(dataContent);
//加入图片数据
foreach (byte[] imgBytes in byteses)
{
HttpContent byteArray = new ByteArrayContent(imgBytes);
byteArray.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment")
{
FileName = imgBytes.Length.ToString()
};
multipart.Add(byteArray);
}
HttpResponseMessage response = httpClient.PostAsync(url, multipart).Result;
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
string s = t.Result;
//Newtonsoft.Json
string jsonNamespace = DeserializeObject<T>(s).ToString();
result = DeserializeObject<T>(s);
}
}
}
return result;
}
Form窗体
动态处理PictureBox的操作代码
#region FlowPanel操作
/// <summary>
/// 初始化FlowPanel
/// </summary>
private void InitPnl()
{
flowpnl.Controls.Clear();
}
/// <summary>
/// 根据文件名显示图片
/// </summary>
/// <param name="filename"></param>
private void AddPic(string filename)
{
int counts = flowpnl.Controls.Count;
int idx = counts == 0 ? 1 : counts + 1;
PictureBox pic = new PictureBox();
pic.SizeMode = PictureBoxSizeMode.StretchImage;
pic.ImageLocation = filename;
pic.Tag = idx;
pic.Name = "pic" + idx;
pic.Width = 150;
pic.Height = 150;
flowpnl.Controls.Add(pic);
}
/// <summary>
/// 根据图片byte数组显示图片
/// </summary>
/// <param name="member"></param>
private void AddPic(CVipMemberPic member)
{
int counts = flowpnl.Controls.Count;
int idx = counts == 0 ? 1 : counts + 1;
PictureBox pic = new PictureBox();
pic.SizeMode = PictureBoxSizeMode.StretchImage;
pic.Image = ImgbyteApi.BytesToImage(member.Photo);
pic.Tag = member.Photoidx;
pic.Name = "pic" + member.Photoidx;
pic.Width = 150;
pic.Height = 150;
flowpnl.Controls.Add(pic);
}
/// <summary>
/// 删除图片
/// </summary>
/// <param name="picture"></param>
private void DelPic(PictureBox picture)
{
foreach (PictureBox control in flowpnl.Controls)
{
if (control.Name == picture.Name)
{
flowpnl.Controls.Remove(control);
}
}
}
#endregion
上传图片
private void btnupload_Click(object sender, EventArgs e)
{
lblmsg.Text = "";
if (flowpnl.Controls.Count > 0)
{
List<byte[]> bytes = new List<byte[]>();
foreach (PictureBox item in flowpnl.Controls)
{
bytes.Add(ImgbyteApi.ImageToBytes(item.Image));
}
CRequest<string> request = new CRequest<string>();
request.ReqData = "00001";
TransSignApi.CreateRequestSign(ref request);
string poststr = JsonConvert.SerializeObject(request);
string transurl = textBox1.Text + "/Uploadfile";
try
{
CResponse<List<CVipMemberPic>> response = WebapiHelper.PostWebAPI<CResponse<List<CVipMemberPic>>>
(transurl, poststr, bytes);
lblmsg.Text = response.ResMsg;
}
catch (Exception ex)
{
lblmsg.Text = ex.Message;
}
}
}
下载图片
private void btndownload_Click(object sender, EventArgs e)
{
//初始化
lblmsg.Text = "";
InitPnl();
CRequest<string> request = new CRequest<string>();
request.ReqData = "00001";
TransSignApi.CreateRequestSign(ref request);
string url = textBox1.Text + "/Downloadfile" + "?Sign=" + request.Sign
+ "&Ts=" + request.Ts + "&ReqData=" + request.ReqData;
try
{
var response = WebapiHelper.GetWebAPI<CResponse<List<CVipMemberPic>>>(url);
lblmsg.Text = response.ResMsg;
if (response.ResId == 1)
{
foreach (var item in response.ResData)
{
AddPic(item);
}
}
}
catch (Exception ex)
{
lblmsg.Text = ex.Message;
}
}
操作效果
选择本地图片
下载图片
服务端有三张图片,我们本地四张,所以点击下载后只显示服务端存在的三张图片
-END-
Vaccae的往期经典
OpenCV
《OpenCV4Android NDK方式进行Canny边缘检测》
《OpenCV4Android NDK方式TesserartOCR实时进行识别》
《OpenCV4Android NDK级联方式实时进行人脸检测》
Android
《Android利用SurfaceView结合科大讯飞修改语音实别UI》
《Android关于语音识别的功能实现分析(一)---结构化思维》
《Android关于语音识别的功能实现分析(二)---语义解析》
《Android中RecyclerView嵌套RecyclerView》
.Net C#
数据库及其它
《SQL Server中With As的介绍与应用(三)--递归的实战应用》
《Oracle利用row_number()over()方式解决插入数据时重复键的问题》
长按下方二维码关注微卡智享