У меня есть HTML / JS клиент сторона, которая связывается со nodejs / express сервер сторона. Клиент отправляет файл на сервер узла - пока все работает нормально. Сервер узла вызывает https.request для отправки двоичных данных на nother ASP. NET Core 3 компонент (сервер). Проблема в том, что контроллер ASP. NET Core 3.1 продолжает получать ошибки / пустые данные. API: TransferModel из controller.cs либо получает пустой массив данных, либо генерирует исключения (зависит от изменений, которые я делаю в nodejs)
Client / HTML Side
<label style="font-weight: bold;">Upload Model File...</label>
<form action="fileupload" method="post" enctype="multipart/form-data">
<input type="file" name="filetoupload"><br>
<br><input class="button" type="submit">
</form>
Node JS Завершить - частичное
var express = require('express');
const path = require('path');
var bodyParser = require("body-parser");
const plantAPI = require('./plantSimAPI')
var formidable = require('formidable');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
var serverUrl = 'localhost'
var port = '5000'
app.post('/fileupload', (req, res) => {
var form = new formidable.IncomingForm();
form.keepExtensions = true;
form.onPart = function (part) {
if (!part.filename) {
// let formidable handle all non-file parts
form.handlePart(part);
return;
}
part.on('data', function (data) {
transferModel(data);
});
part.on('end', function () {
transferModel([]);
res.send(200);
});
part.on('error', function (err) {
// handle this too
res.json(err);
});
}
form.parse(req, function (err, fields, files) {
//pass the file to the plant sim server
// plantSim.
//res.send(200);
console.log('ahmad');
});
});
function transferModel(data, ondone) {
this.callPlantSimAPI2('/plantsim/api/model/transfer', 'PUT', data, () => {
if (ondone) ondone();
});
}
function callPlantSimAPI2(path, method, data, onDone) {
const options = {
host: serverUrl,
port: port,
path: path,
method: method,
agent: new https.Agent({
rejectUnauthorized: false,
}),
headers: {
"Content-Type": "multipart/form-data" //"application/octet-stream"
}
};
var req = https.request(options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + path + ' : ' + chunk);
if (onDone) onDone(chunk);
});
res.on('error', (err) => {
if (onDone) onDone("")
});
res.on('end', () => {
if (onDone) onDone("")
})
});
req.on('error', function (e) {
console.log('problem with request: ' + e.message);
if (onDone) onDone("");
});
// write data to request body
if(data && data.length>0) req.write(data);
req.end();
}
ASP. NET Web API Core3.1
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
//first routing
app.UseRouting();
//then
app.UseCors(
options => options.SetIsOriginAllowed(x => _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials()
);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Controller.cs
namespace PlantSimAPI.Controllers
{
[ApiController]
[EnableCors("simapi")]
[Route("plantsim/api")]
public class PlantSimAPIController : ControllerBase
{
[HttpPut]
[Route("model/transfer")]
public async Task<IActionResult> TransferModel( [FromBody]byte[] data)
{
try
{
//byte[] data = { };
using (var ms = new MemoryStream(1024*8))
{
await Request.Body.CopyToAsync(ms);
data = ms.ToArray();
//do something with my data
}
return Ok();
}
catch (Exception ex)
{
//Log message
this._logger.LogError(ex.Message);
//return bad result
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
}
}