c# - 使用 HttpWebRequest 从 C# 上传图像到使用 PUT 方法的 NodeJS Express
问题描述
我有这部分 C# 代码可以与另一个我无权访问的 NodeJS Express 应用程序一起正常工作,我想保留此代码原样。
string filetoupload = @"D:\testvideo.mp4";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://127.0.0.1:10090" + "/upload?name=" + WebUtility.UrlEncode(Path.GetFileName(filetoupload)));
request.Method = "PUT";
request.ContentType = MimeTypesMap.GetMimeType(Path.GetExtension(filetoupload));
using (FileStream fs = File.OpenRead(filetoupload))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
request.ContentLength = buffer.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
WebResponse upresponse = request.GetResponse();
Stream updataStream = upresponse.GetResponseStream();
StreamReader upreader = new StreamReader(updataStream);
string upres = upreader.ReadToEnd();
Console.WriteLine("RES: " + upres);
}
问题是我不知道如何在 NodeJS Express 端正确读取流数据。我已经设法阅读它并使用此代码将文件存储在磁盘上
const express = require('express');
const fs = require('fs');
const app = express();
const port = process.env.PORT || 10090;
app.listen(port, () =>
console.log(`App is listening on port ${port}.`)
);
app.put('/upload', async (req, res) => {
try {
var socket = req.socket;
socket.on('data', function(data) {
fs.appendFile("somevideo.mp4", new Buffer(data), function (err,data) {
if (err) {
res.status(500).send(err);
}
});
});
res.send({
status: true,
message: 'File uploaded'
});
} catch (err) {
res.status(500).send(err);
}
});
但是在文件存储在磁盘上之后我需要做更多的工作(创建哈希码,做一些 MySQL 工作等),然后返回一些文本数据作为响应消息。对我来说,问题是如何知道那是什么时候发生的?
是否有另一种(正确的)方法来存储像这样上传的文件?
解决方案
这些天我做了一些类似的工作。它使用 multer 将多个图像 + 输入数据从 Laravel (PHP) 上传到 Node.js 作为多部分表单数据。老实说,我不了解 C#,可能您需要更改 C# 代码中的某些内容,但我认为 C# 方面没有太多工作。此外,为简单起见,您可以查看此线程。
IMO 这在 Node.js 部分可能对您有用,因为此代码不依赖于客户端语言。
在某处创建 Multer 的实用程序(本例中为“utilities/multer.js”):
const multer = require('multer');
const path = require('path');
module.exports = {
fileUpload: function () {
return multer({
storage: multer.diskStorage({
destination: function (req, file, cb) {
const filePath = path.join(__dirname, './../uploads');
cb(null, filePath);
},
filename: function (req, file, cb) {
const extension = 'mp4';
const dateField = (new Date().getTime() / 1000 | 0);
const randomField = Math.random().toString(36).substring(2);
const fileName = `${dateField}-${randomField}.${extension}`;
cb(null, fileName);
},
}),
limits: {
fileSize: 1024 * 1024 * 20 // max file size in MB
},
fileFilter: (req, file, cb) => {
let valid = (file.mimetype === 'text/plain');
cb(null, valid);
},
});
}
};
在您的路线中添加适当的路线(本例中为“routes/item.js”):
const { Router } = require('express');
const router = Router();
const itemController = require('./../controllers/item');
const fileUpload = require('./../utilities/multer').fileUpload();
router.put('/upload',
fileUpload.any('files', 10), // uploading files max count
itemController.create);
// other routes ...
module.exports = router;
现在在您的控制器中,您可以继续编码(本例中为“controllers/item.js”):
module.exports = {
create: async (req, res) => {
if (req.files.length === 0) {
return res.status(403).json({
error: "File(s) required!"
});
}
const parsedData = JSON.parse(req.body.data);
// some code block ...
return res.status(201).json({
title: parsedData.title,
description: parsedData.description,
});
},
};
不要忘记根据您的需要自定义此代码。无论如何,这对我来说非常有用。
另外,由于我不确定 C# 代码,因此我可以使用我使用过的 Postman 提供请求信息:
这是 Postman 针对适当请求默认生成的 C# (RestSharp) 代码:
var client = new RestClient("http://localhost:3000/api/v1/item/upload");
client.Timeout = -1;
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer CUSTOMER_ID_TOKEN");
request.AddFile("files", "/home/user/Downloads/video1.mp4");
request.AddFile("files", "/home/user/Downloads/video2.mp4");
request.AddParameter("title", "This is an awesome product!");
request.AddParameter("description", "This is an awesome product!");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
推荐阅读
- html - 无法在 SVG 中显示度数字符 (°)
- javascript - Visual Studio 不为 ASP.Net 的班级成员提供建议
- firebase - Firebase 安全规则仅读取特定项目
- .net - CosmosDb 存储过程调用
- google-bigquery - 如何检查 BigQuery 表中所有分区/分片的列类型
- python - Python 文件计数器脚本无法正常工作
- ios - 在 swift 4 中使用 UserNotifications 重复本地通知
- mongodb - Yii2中的MongoDB字符串字段值长度
- powershell - 如何使用 PowerShell 从文件名中删除表情符号?
- amazon-web-services - 使用 pip 在实例上安装 aws cli