首页 > 其他分享 >.Net Web API 005 Controller上传小文件

.Net Web API 005 Controller上传小文件

时间:2023-08-05 22:57:06浏览次数:39  
标签:Web set string get Controller API var new public

1、附属文件对象定义

一般情况下,系统里面的文件都会附属一个对象存在,例如用户的头像文件,会附属用户对象存在。邮件中的文件会附属邮件存在。所以在系统里面,我们会创建一个附属文件对象,命名为AttachedFileEntity。其定义如下所示。

/// <summary>
/// 附属文件实体对象
/// </summary>
public class AttachedFileEntity
{

    /// <summary>
    /// 实体对象GUID
    /// </summary>
    public string GUID { get; set; } = "";

    /// <summary>
    /// 所属对象的GUID
    /// </summary>
    public string EntityGUID { get; set; } = "";

    /// <summary>
    /// 名称
    /// </summary>
    public string Name { get; set; } = "";

    /// <summary>
    /// 关键字
    /// </summary>
    public string KeyWord { get; set; } = "";

    /// <summary>
    /// 文件大小
    /// </summary>
    public int FileSize { get; set; } = 0;

    /// <summary>
    /// 服务器存储路径
    /// </summary>
    public string ServerPath { get; set; } = "";

    /// <summary>
    /// 描述信息
    /// </summary>
    public string Description { get; set; } = "";

}

EntityGUID属性的作用是,定义该文件属于哪个实体对象,例如某个用户的头像文件,该属性就是这个用户对象的GUID值。

KeyWord属性用来标识文件。例如UserEntity有两个文件,头像和一个自我介绍的视频文件。这两个文件的EntityGUID都是UserEntity的GUID,那么就可以通过KeyWord来区分两个文件是做什么用的。

2、小文件上传服务

如果一个文件比较小,例如3M以内,那么我们就可以一次性把文件上传上来,上传的时候,要把AttachedFileEntity对象传进来,并添加到数据库中。

代码如下所示。

 /// <summary>
/// 上传文件
/// </summary>
/// <param name="pEntity"></param>
/// <returns></returns>
[HttpPost]
[Route("UploadFile")]
public IActionResult UploadFile()
{
    //获取客户端传来的数据
    var myEntityJosnString = Request.Form["pEntity"].ToString();
    var myEntity = JsonSerializer.Deserialize<AttachedFileEntity>(myEntityJosnString);
    var myFile = Request.Form.Files[0];

    //设置新的文件路径
    string myFileEx = Path.GetExtension(myFile.FileName);
    string myServerFilePath = DateTime.Now.ToString("yyyy_MM_dd") + "\\" + Guid.NewGuid().ToString() + myFileEx;
    myEntity!.ServerPath = myServerFilePath;

    //创建目录
    string myFullServerPath = AppDomain.CurrentDomain.BaseDirectory + "\\Files\\" + myServerFilePath;
    string myFullFolder = Path.GetDirectoryName(myFullServerPath)!;
    if (Directory.Exists(myFullFolder) == false)
    {
        Directory.CreateDirectory(myFullFolder);
    }

    Stream? myStream = null;
    FileStream? myFileStream = null;
    BinaryWriter? myBinaryWriter = null;
    try
    {
        myStream = myFile.OpenReadStream();
        byte[] myBytes = new byte[myStream.Length];
        myStream.Read(myBytes, 0, myBytes.Length);
        myStream.Seek(0, SeekOrigin.Begin);

        myFileStream = new FileStream(myFullServerPath, FileMode.Create);
        myBinaryWriter = new BinaryWriter(myFileStream);
        myBinaryWriter.Write(myBytes);
    }
    finally
    {
        myBinaryWriter?.Close();
        myFileStream?.Close();
        myStream?.Close();
    }

    //把附属文件对象保存到数据库中
    //代码略

    return this.Ok(myEntity);
}

因为我们要传入两个复杂的对象AttachedFileEntity和File,所以就不能用参数接了,就需要用代码从Request里面读取。文件其本质就是二进制数据,我们获取这个二进制之后,把数据保存成文件就可以了。然后把pEntity写入到数据库中。

3、前端调用

先用桌面端测试,界面是用C#写的WPF桌面软件,入下图所示。

截图.png

调用代码入下所示。

var myFilePath = this.UI_SmallFile_TextBox.Text.Trim();
if (myFilePath.Length == 0)
{
    MessageBox.Show("请选择一个文件。");
    return;
}
if (File.Exists(myFilePath) == false)
{
    MessageBox.Show("文件不存在,请重新选择。");
    return;
}

//定义AttachedFileEntity
var myAttachedFileEntity = new AttachedFileEntity()
{
    GUID = Guid.NewGuid().ToString(),
    Name = "用户头像",
    KeyWord = "UserProfilePhoto",
    Description = "",
    EntityGUID = "AAAA"
};

//定义请求内容
var myFileStream = new FileStream(myFilePath, FileMode.Open);
myAttachedFileEntity.FileSize = (int)myFileStream.Length;
var myFileName = Path.GetFileName(myFilePath);
var myFileStreamContent = new StreamContent(myFileStream);
var myMultipartFormDataContent = new MultipartFormDataContent
{
    { JsonContent.Create(myAttachedFileEntity), "pEntity" },
    { myFileStreamContent, "pFormFile", myFileName }
};

//请求服务
var myHttpClientEx = new HttpClientEx(new HttpClient())
{
    Url = "http://localhost:5000/api/AttachedFile/UploadFile",
    HttpContent = myMultipartFormDataContent
};
await myHttpClientEx.PostAsync();
myFileStream.Close();

//解析结果
if (myHttpClientEx.IsSuccess == false)
{
    MessageBox.Show(("上传文件失败," + myHttpClientEx.ResponseContenString));
    return;
}
var myEntity = myHttpClientEx.GetResponseObject<AttachedFileEntity>();
var myEntityJosnString = JsonSerializer.Serialize(myEntity);
MessageBox.Show(myEntityJosnString);

HttpClientEx是对.Net定义的HttpClient一些功能的扩展,这样用起来会比较方便,代码定义如下。

/// <summary>
/// HttpClient的自定义扩展类
/// </summary>
public class HttpClientEx
{

    /// <summary>
    /// HttpClient的自定义扩展类
    /// </summary>
    /// <param name="pHttpClient"></param>
    public HttpClientEx(HttpClient? pHttpClient)
    {
        this.HttpClient = pHttpClient;
        this.ParameterDictionary = new Dictionary<string, string>();
    }

    /// <summary>
    /// HttpClient对象
    /// </summary>
    public HttpClient? HttpClient { get; private set; }

    /// <summary>
    /// 服务地址
    /// </summary>
    public string Url { get; set; } = "";

    /// <summary>
    /// 参数字典
    /// </summary>
    public Dictionary<string, string> ParameterDictionary { get; private set; }

    /// <summary>
    /// 请求内容
    /// </summary>
    public HttpContent? HttpContent { get; set; }

    /// <summary>
    /// 请求返回的消息
    /// </summary>
    public HttpResponseMessage? ResponseMessage { get; private set; }

    /// <summary>
    /// 是否执行成功
    /// </summary>
    public bool IsSuccess { get; private set; }

    /// <summary>
    /// 返回的内容字符串
    /// </summary>
    public string ResponseContenString { get; private set; } = "";

    /// <summary>
    /// Get
    /// </summary>
    /// <returns></returns>
    public async Task GetAsync()
    {
        var myUrlWithParameters = this.GetUrlWithParameters();
        this.ResponseMessage = await this.HttpClient!.GetAsync(myUrlWithParameters);
        this.IsSuccess = this.ResponseMessage.IsSuccessStatusCode;
        this.ResponseContenString = await this.ResponseMessage.Content.ReadAsStringAsync();
    }

    /// <summary>
    /// Get
    /// </summary>
    /// <returns></returns>
    public async Task PostAsync()
    {
        var myUrlWithParameters = this.GetUrlWithParameters();
        this.ResponseMessage = await this.HttpClient!.PostAsync(myUrlWithParameters, this.HttpContent);
        this.IsSuccess = this.ResponseMessage.IsSuccessStatusCode;
        this.ResponseContenString = await this.ResponseMessage.Content.ReadAsStringAsync();
    }

    /// <summary>
    /// 得到返回的对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T? GetResponseObject<T>()
    {
        if (this.ResponseContenString == "")
        {
            return default;
        }
        var myJsonSerializerOptions = new JsonSerializerOptions()
        {
            PropertyNameCaseInsensitive = true
        };
        return JsonSerializer.Deserialize<T>(this.ResponseContenString, myJsonSerializerOptions);
    }

    /// <summary>
    /// 得到带参数的Url
    /// </summary>
    /// <returns></returns>
    private string GetUrlWithParameters()
    {
        if (this.ParameterDictionary == null)
        {
            return this.Url;
        }
        if (this.ParameterDictionary.Count == 0)
        {
            return this.Url;
        }

        var myParameterList = new List<string>();
        foreach (var myItem in this.ParameterDictionary)
        {
            myParameterList.Add(myItem.Key + "=" + myItem.Value);
        }
        return this.Url + "?" + string.Join("&", myParameterList);
    }

}

如果客户端是Js,就需要自己组织服务需要的数据了。代码入下所示。

var myFileReader = new FileReader();
var myFileName = "";

myFileReader.onloadend = function () {
    var myFileResult = myFileReader.result;
    var myFileLength = myFileResult.byteLength;

    var myFileEntity = new Object()
    {
        ServerPath: ""
    };
    Upload();

    function Upload() {

        var myByteArray = myFileResult.slice(0, myFileLength);
        var myBlob = new Blob([myByteArray]);
        var myFile = new File([myBlob], myFileName);
        var myFormData = new FormData();
        myFormData.append("file", myFile)
        myFormData.append("pEntity", json.stringify(myFileEntity));
        request.post(myUrl, {
            data: myFormData
        }).then(function (data) {
            myFileEntity = json.parse(data);
            alert("上传文件结束。");
            alert(json.stringify(myFileEntity));
        }, function (err) {
            alert(err);
            return;
        });
    }
}

myFileName = this.files[0].name;
myFileReader.readAsArrayBuffer(this.files[0]);

标签:Web,set,string,get,Controller,API,var,new,public
From: https://www.cnblogs.com/mytudousi/p/17608801.html

相关文章

  • OpenApi(Swagger)快速转换成 TypeScript 代码 - STC
    在现代的Web开发中,使用OpenAPI(以前称为Swagger)规范来描述和定义API已经成为一种常见的做法。OpenAPI规范提供了一种统一的方式来描述API的结构、请求和响应,使得开发人员能够更好地理解和使用API。然而,手动编写与OpenAPI规范匹配的客户端代码或服务端框架可能是一项繁......
  • 创建一个基于SpringBoot的web项目
    1、使用国内地址创建SpringBoot项目国内地址:https://start.springboot.io/2、项目结构1:Java目录下放Java相关文件2:static目录下放.css.html.js等文件,包括图片之类的3:templates目录下放模板文件4:放SpringBoot主要配置文件3、创建基于SpringBoot的web案例在上面基础之上,进行下......
  • 漏洞发现-web应用之漏洞探针利用修复
    原理分析1.已知CMS---如常见的dedecms.discuz,wordpress等源码结构,这种一般采用非框架类开发,但也有少部分采用的是框架类开发,针对此类源码程序的安全检测,我们要利用公开的漏洞进行测试,如不存在可采用白盒代码审计自行挖掘。(1.在漏洞平台如seebug、cnvd搜索关键字2.使用工具......
  • 10.2 web服务器
    Web客户端和服务器之间的交互用的是一个基于文本的应用级协议,叫做HTTP(HypertextTransferProtocol,超文本传输协议)。HTTP是一个简单的协议。一个Web客户端(即浏览器)打开一个到服务器的因特网连接,并且请求某些内容。服务器响应所请求的内容,然后关闭连接。浏览器读取这些内容,并把......
  • WebSocket
    1.使用前端jsfunctioncreateScoket(token){varsocket;if(typeof(WebSocket)=="undefined"){console.log("您的浏览器不支持WebSocket");}else{varhost=window.location.origin.replace("http:","ws:&quo......
  • 探索ASP.NET Framework WebAPI的简介与应用
    一、什么是WebAPI?1.1-什么是WebAPI?WebAPI是一种用开发系统接口、设备接口API的技术,基于Http协议,请求和返回格式默认是Json格式。比WCF简单、更通用;比WebService更节省流量,更简洁。1.2-WebAPI的特点?Action方法直接返回对象,专注于数据更符合Restful的风格有利于独立于IIS部署Action可......
  • 探索ASP.NET Framework WebAPI的简介与应用
    一、什么是WebAPI?1.1-什么是WebAPI?WebAPI是一种用开发系统接口、设备接口API的技术,基于Http协议,请求和返回格式默认是Json格式。比WCF简单、更通用;比WebService更节省流量,更简洁。1.2-WebAPI的特点?Action方法直接返回对象,专注于数据更符合Restful的风格有利于独立于IIS部......
  • 增强型Web安全网关在银行的应用
    销售,绝不是降低身份去取悦客户,而是像朋友一样给予合理的建议。你刚好需要,我刚好专业!仅此而已! 乔.吉拉德健康的安全体系,还可以更完善   浙江某商业银行股份有限公司是一家成立多年的商业银行,对于网络安全和数据安全的建设已经非常完善。作为成立多年的商业银行,对于网络安全和......
  • web前端技能方法总结(css、js、jquery、html)(3)
    HTML(HyperTextMarkupLanguage)就是超文本标记语言。"超文本"就是表示页面内可以包含非文字元素,如:图片、链接、音乐等等。它是一种建立网页文件的语言,通过标记式的指令(Tag),将影像、声音、图片、文字等链接显示出来。这种标记性语言是因特网上网页的主要语言。HTML网页文件可以使用......
  • 使用webp格式拯救你的硬盘
    使用webp格式拯救你的硬盘什么是webp格式?WebP是一种现代图像格式,可提供卓越的无损和网络上图像的有损压缩。使用WebP、网站管理员和网络开发人员可以创建更小、更丰富的图像,使Web更快。与PNG相比,WebP无损图像的尺寸小了26%。有损图像比同等SSIM质量指数下的同类JPEG......