简体   繁体   中英

Post file from NodeJS to C# WCF

I'm currently setting up a nodejs server, but an action on that server is to generate a report with jsreport, save it locally and later send it to another service of ours, this being WCF.

In WCF, receive a Stream and save the file in our default directory.

Testing the request on Insomnia, to send a file, works perfectly. But through Node, using Axios or Request, communication occurs, but the generated file is 1kb.

Here is the excerpt from the NodeJS call.

To make de request, I'm using the module Request, v ^2.88.2. (But I've tried with Axios, also)

const formData2 = { 
                            file: fs.createReadStream(reportFile) //the file path
                        }

                        request.post({
                            url: urlSend,//Url of post
                            headers: {
                                'Content-Type': 'multipart/form-data' 
                            },
                            formData: formData2,
                        }, function(error, response, body) {
                            console.log(response);
                        });

The inside of the .pdf file has something like

----------------------------209853603972788926274398 Content-Disposition: form-data; name="file"; filename="APR-RST-06-REV-00.pdf" Content-Type: application/pdf

%PDF-1.4 %׃כיב 1 0 obj <

My C# code where the file is send to (I've made some changes, to remove other codes):

public string uploadFileReport(string arg1, string arg2, string arg3, string arg4, string arg5, Stream file)
        { 

            try
            {  
                if (string.IsNullOrEmpty(arg1) || string.IsNullOrEmpty(arg2) || string.IsNullOrEmpty(arg3))
                    throw new Exception("Um ou mais parâmetros não foram encontrados");

                string diretorioData = "C:\\DATA\\"; 

                //Nome do arquivo.
                string fileName = (string.IsNullOrEmpty(arg5) ? "relatório.pdf" : arg5); 
                string directoryPath = diretorioData + "CRM\\"; 

                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }


                 int length = 0;
                 using (FileStream writer = new FileStream(directoryPath + "\\"+fileName, FileMode.Create))
                 {
                     int readCount;
                     var buffer = new byte[8192];
                     while ((readCount = file.Read(buffer, 0, buffer.Length)) != 0)
                     {
                         writer.Write(buffer, 0, readCount);
                         length += readCount;
                     }
                 }

                return JsonConvert.SerializeObject(new
                {
                    status = "OK", 
                }, Formatting.Indented);
            }
            catch (Exception exc)
            {
                return JsonConvert.SerializeObject(new
                {
                    status = "NOK",
                    message = exc.Message
                }, Formatting.Indented);
            }

        }

For some reason, this Method needed the UriTemplate, on the Interface File. But, to work, on node, I needed to send this values as url param. Perhaps this is the reason, but as I say, from Insomnia, this method works fine.

  [WebInvoke(Method = "POST",
           BodyStyle = WebMessageBodyStyle.WrappedRequest,
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "/uploadFileReport?arg1={arg1}&arg2={arg2}&arg3={arg3}&arg4={arg4}&arg5={arg5}")]
        [OperationContract]
        string uploadFileReport(string arg1, string arg2, string arg3, string arg4, string arg5, Stream file);

WCF doesn't support Formdata by default, it can be properly handled with the third-party library,
https://archive.codeplex.com/?p=multipartparser
Besides, With enabling stream in WCF, the signature of a function cannot contain more than one argument.
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-enable-streaming
Can you access the service description page properly? I don't think the service can work normally, although you said you can make it work perfectly.
Please refer to this link for the solution to uploading files.
How to upload image of various type (jpg/png/gif) to the server through Stream using WCF web API
Feel free to let me know if there is anything I can help with.

For those who may run into this same problem, here's how I manage it. I've changed my request.post to something like:

 const options2 = {
                                method: "POST",
                                url: urlSend,
                                headers: {
                                    "Authorization": "Bearer " + token, 
                                    "Content-Type": "application/octet-stream", 
                                },
                                encoding: 'binary',
                                multipart: [ 
                                    {  
                                        body: fs.createReadStream(reportFile) 
                                    }
                                ],
                            };  

request(options2, function (err, res, body) {
});

And, on my WCF web.config, I've added a binding so accept larger files:

 <binding name="UploadBinding"
                transferMode="Streamed"
              maxBufferPoolSize="2000000000"
              maxBufferSize="2000000000"
                receiveTimeout="01:00:00"
                sendTimeout="01:00:00"
                maxReceivedMessageSize="2000000000" >

          <readerQuotas maxDepth="2000000000"
               maxStringContentLength="2000000000"
               maxArrayLength="2000000000"
               maxBytesPerRead="2000000000"
               maxNameTableCharCount="2000000000" />
        </binding>

And last, added this binding to the service

      <service name="WCFService.CRMH0001">
        <endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding" bindingConfiguration="UploadBinding"
         contract="WCFService.ICRMH0001" />
      </service>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM