Sending images from a C# application to a NodeJS Express server using the PUT method through HttpWebRequest

I have a C# code snippet that is successfully working with another NodeJS Express application, the source code of which I do not have access to. However, I want to keep this code unchanged.

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);
}

The issue arises when trying to properly read stream data on the NodeJS Express server side. I have managed to store the file on disk using the following code:

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);
    }
});

However, I need to perform additional tasks after the file is stored on disk (such as creating a hash code, MySQL operations, etc.) and then return text data as a response message. The challenge for me is determining when these tasks are completed.

Is there a better approach to handle file uploads like this?

Answer №1

Recently, I undertook a project that involved uploading multiple images and input data from Laravel (PHP) to Node.js using multer for handling multipart form data. While I am not familiar with C#, you may need to make some adjustments to your C# code. However, the majority of the work should be on the Node.js side. For simplicity, you can refer to this thread.

In my opinion, the utility provided for Node.js in the following code snippet can be quite beneficial, as it is independent of the client-side language being used.

To create Multer's utility, place the following code in a file named "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);
            },
        });
    }
};

Incorporate the appropriate route into your routes file (e.g., "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), // maximum number of files to upload
    itemController.create);
// other routes ...

module.exports = router;

You can now proceed with coding in your controller file (e.g., "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);

        // additional code block ...    

        return res.status(201).json({
            title: parsedData.title,
            description: parsedData.description,
        });
    },
};

Remember to customize the code as per your requirements. This setup worked perfectly for me, but adjustments may be needed for your specific use case.

If you are unsure about the C# code, I can provide the Postman request info that I used:

https://i.stack.imgur.com/GtUQz.png

The following is the default C# (RestSharp) code generated by Postman for the corresponding request:

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);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

`npm security check reveals a potential vulnerability related to Inefficient Regular Expression Complexity. For more information, refer to: https://github.com/advisories/GHSA-9vvw-cc

# npm audit report debug <3.1.0 debug Inefficient Regular Expression Complexity vulnerability - https://github.com/advisories/GHSA-9vvw-cc9w-f27h No solution currently available node_modules/body-parser/node_modules/debug node_modules/express/node_modu ...

Indicate whether all properties should be designated as mandatory or optional in Joi validations

Currently, I am creating an Express API and incorporating @hapi/joi for validation purposes. However, I have encountered a dilemma: when validating a new user, all properties in the schema must be mandatory. On the other hand, when a client wants to update ...

Mac OS reports an Illegal instruction: 4 error when running NodeJS

Each time I try to execute my program, it gives me an Illegal instruction: 4 error without any clue as to why. The code snippet in question: glob('/path/music/*.mp3', function(error, files) { for(var i = 0; i < files.length; i++) { songs ...

Screen content of a post request in Node.js

Can this code in node.js + express be simplified? // Code snippet for registering a new participant app.post('/api/participant', function (req, res, next) { var data = req.body; // Ensure only specific fields are uploaded var parti ...

Messages are not being emitted from the socket

I've been encountering an issue with message transmission from client to server while using React and ExpressJS. When I trigger the sendMessage function on the client side, my intention is to send a message to the server. However, for some reason, the ...

Building a single page web application using TypeScript and webpack - a step-by-step guide

For a while now, I've been working on single page applications using Angular. However, I'm interested in creating a single page application without utilizing the entire framework. My goal is to have just one .html file and one javascript file, w ...

While trying to post data in MongoDB Atlas using Node.js (Express), I encountered an error message stating UnknownReplWriteConcern

Encountering an issue when attempting to post data in MongoDB atlas. const express = require('express'); const router = express.Router(); const Persons = require('./PersonsSchema'); router.post('/',async(req,res)=>{ ...

What is the reason behind not being able to assign identical names to my SailsJS models and MySQL tables?

Recently diving into Sails JS, I found myself in unfamiliar territory with RESTful APIs. Following the guide, I created a User model to correspond with my existing users table. Adding attributes based on the table's columns was straightforward, and a ...

Exploring the compatibility of Husky with Typicode using Yarn

Currently, I have implemented the use of husky to configure git hooks for prettier. However, I am facing a persistent issue whenever I attempt to commit or push: > husky - Can't find npm in PATH. Skipping precommit script in package.json My curre ...

Tips for efficiently adding a like feature to a MEAN web application

Currently, I am in the process of developing a web application that allows users to express their preferences by liking certain choices displayed on the page. I am trying to optimize the efficiency of the like/unlike system. My main question is whether ev ...

Using Javascript to parse SOAP responses

Currently, I am working on a Meteor application that requires data consumption from both REST and SOAP APIs. The SOAP service is accessed using the soap package, which functions properly. However, I am facing challenges with the format of the returned data ...

Simple steps to sort Facebook API events according to the date

I am using the Facebook events API to retrieve upcoming events from a public page. However, I only want to display events that have not yet passed. To achieve this, I need to filter them by date. Below is the code snippet I am currently using: FB.api( & ...

I encounter an issue when attempting to fetch data from multiple tables

I'm facing an issue with my query const a = await prisma.$queryRaw` SELECT r.name as name, r.profileId as profile, o.lastName as lastName FROM UserSetting r , User o WHERE r.userId=o.id ` After running the query, I am getting an error message stating ...

Matching the cookie and header in express.js CSURF results in a 403 error code

My express server setup is quite simple: app.use(bodyParser.json()); app.use(cookieParser()); app.use(csurf({ cookie: true })); // routes app.use(Routes imported from another file); Currently, the client side consists of a basic form in react. ...

Error: Unable to locate module: Could not find '@/styles/globals.scss'

I'm encountering an error message with my import statement for the SCSS file in my _app.tsx. Can someone help me find a solution? I'm working with Next.js and have already exhausted almost every resource available online to fix this issue. ...

What are the steps to incorporate metrics middleware for Socket IO notifications, specifically monitoring both emitted events and listener activity?

I am currently working on a project that involves tracking all socket.io notification transactions initiated by the server, resembling an API request/response counter to validate subscription validation. Our team is utilizing an express middleware to moni ...

The subcategory was not factored into my npm package

In my npm module 'ldap-pool', I'm facing an issue where the '@types/ldapjs' package, which is a dependency along with 'ldapjs', does not get installed when I add 'ldap-pool' to another project. This particular s ...

Regarding passing input into a JavaScript class method that is exported through the exports keyword

The inquiry at hand relates to ExtendScript code, however, I believe it should be independent of any specific javascript implementation. If we have the following in a JS library file (base64.js) exports.encode64 = encoder('+/'); //... function ...

How to extract response body from Axios without decompressing it from gzip

I currently have two express servers in my setup. One server functions as the backend, handling queries to the database, while the other serves as a proxy to redirect requests. Every data request from the frontend is made through the proxy, which then sen ...

Having trouble launching simple ionic template: Issue with locating module 'fast-deep-equal'

Recently I started using Ionic and followed the steps to install the basic blank template as shown below. First, I installed Ionic and Cordova by running the command: npm install -g ionic Cordova. After that, I created my first Ionic project using the f ...