Flutter Dio multipart image, Cannot read property '0' of undefined - flutter

I am trying to send multiple images to the backend server.
I have tried Dio and Http but the server responds with an error and the rest of the data except the images get saved.
The documentation says that the key values must be 'images_0' 'images_1' and so on.
Code -
The images are converted from XFile to multipart file.
int imgNum = 0;
for (int i = 0; i < data.images.length; i++) {
if (data.images[i] != null) {
File file = File(data.images[i]!.path);
String fileName = file.path.split('/').last;
http.MultipartFile mFile = http.MultipartFile(
'images_$imgNum',
file.readAsBytes().asStream(),
await file.length(),
filename: fileName,
);
imgNum++;
request.files.add(mFile);
}
}
(data.images is a list of XFiles? , request is the http.MultipartRequest)
All the other fields and headers are working and being saved correctly.
I have tried using Dio too which gives the same response. The response from the server is :
{data: {error: Cannot read property '0' of undefined}, message: Something went wrong. Please try again later.}
Our project also has a website where the form is working correctly, and when the http request there shows the images as follows : (in Google Chrome)
Under form data
Form Data source
The api team has also shared Swagger Ui API docs-
Docs
What am I doing wrong? How can I fix this?
Thank you for responding.

Related

I POST my image by python through WP REST API, but the response is just the array of items in media library

First of all, I have found out what's wrong with my python code, but I really want some one to tell me how it popped out because I'm just a noob amateur.
I tried to post my album collected on my wordpress by using my python script as usual, but I got an unexpected throw-out when it start to image upload. My img upload function just like this:
def restImgUL(imgPath,imgName,token):
url='http://www.rainloongmusic.com/wp-json/wp/v2/media/'
file_extension = os.path.splitext(imgPath)[-1]
img = open(imgPath,'rb')
imgName = imgName.replace(";","")
_json = {
"title":imgName,
'caption': imgName,
"alt_text":imgName,
"description":imgName,
"status":"publish"
}
image_name = f"{imgName}{file_extension}"
headers = { 'Content-Type': '','Content-Disposition' : 'attachment; filename=%s'%image_name.encode("utf-8").decode("latin1"),"Authorization":"Bearer %s"%token}
res = requests.post(url=url,data=img,headers=headers,json=_json)
rrr = res.json()
if "id" in rrr:
return rrr["id"]
else:
print(rrr)
sys.exit()
The wrong response is an array include items in my first page of media library. I found some clues in rest api handbooks. If I attempt to GET /wp/v2/media, response will be like what I've recieved. But I use POST type request in my python code, I don't really understand what happened there. I have no choice but to try some other methods to bypass this problem. I tried to make a new endpoint and write something like this:
add_action( 'rest_api_init', function () {
register_rest_route( 'rlra/v1', '/media', array(
'methods' => 'POST',
'callback' => 'cmupload',
) );
} );
function cmupload(){
return "This is a test!!!"
}
However, I got rest_no_route when I POST to it. I changed the methods to GET eventually, and got the right text from my server. I think maybe something changed my POST request into a GET one? I tried to figure out with Charles, and found my connection with 302 permanent redirect. So I check my request link and change http into https, everything works.
So, could anyone tell me why a 302 redirect will change my POST request into GET, I've been worn-out due to the lost letter "s" in these days.

Multipart Request in Flutter with MultipartFile.fromBytes

I am trying to send a file to an API with Flutter and the http library.
From a file selector, I get the bytes of the file (a pdf) and create a MultipartRequest as follows:
var request = http.MultipartRequest('PUT', Uri.parse('https://xxx/files'))
..fields['grade'] = 'xxx'
..fields['candidate'] = 'xxx'
..files.add(http.MultipartFile.fromBytes(
'document', file.bytes!, contentType: MediaType('application', 'pdf')));
var response = await request.send();
The request failed, it seems that no binary content is added to this request.
In debug mode I can see that the _stream attribute of the file is null (I am sure that file.bytes contains the file) :
content of the debugging
What did I miss?
I found the problem. Without the optional FileName parameter of the fromBytes method the request is not correctly created. You just need to specify a file name for it to work.

Can't send a document via Telegram API on Swift; using Vapor

Code
let handler16 = TGMessageHandler(filters: .regexp(pattern: "^11$")) {update, bot in
if let id = update.message?.chat.id {
let chatId: TGChatId = .chat(id)
// let file = File(data: "hello", filename: "МЭСК.docx")
let params: TGSendDocumentParams = .init(chatId: chatId, document: .url("http://www.ncbi.nlm.nih.gov/geo/download/?acc=GSE46130&format=file"))
try bot.sendDocument(params: params)
}
}
Error
Type: server Description: Response marked as not Ok, it seems something wrong with request
Code: 400
Bad Request: failed to get HTTP URL contentReason:
How can i save my particular document and send it (if it is big) via Telegram Bot ?
After that I'm running on linux server, i don't know how to do it correct...
If the file is already stored somewhere on the Telegram servers, you don't need to reupload it: each file object has a file_id field, simply pass this FileInfo.fileId("file_id") as a parameter instead of uploading. There are no limits for files sent this way.

Handle uncompleted file upload by API POST endpoint in asp.net core MVC

To simplify the problem let's say I have a simple asp.net mvc endpoint which receives a file. In most of the cases it will be a .jpg one:
[HttpPost]
[Route("appraisal/{appraisalID}/files/{fileSubjectCode}")]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(IEnumerable<AppraisalFileModel>))]
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ModelStateDictionary))]
public async Task<IActionResult> UploadAppraisalFile(int appraisalID, string fileSubjectCode, [FromForm]IFormFile file)
{
file = file ?? Request.Form.Files?.FirstOrDefault();
// intermitent code change to investigate and validate Complete File Size and Actual File Size
var completeFileSizeHeader = Request.Headers["Complete-File-Size"];
int.TryParse(completeFileSizeHeader, out int completeFileSize);
if (file == null || file.Length != completeFileSize)
{
using (var stream = new MemoryStream())
{
await file.CopyToAsync(stream);
stream.Position = 0;
var inputAsString = Convert.ToBase64String(stream.ToArray());
Logger.LogDebug("Complete-File-Size header doesn't much received byteArray size", file.Length, completeFileSize, inputAsString);
}
return StatusCode(StatusCodes.Status411LengthRequired, "Complete-File-Size header doesn't much received byteArray size");
}
// some other logic..
}
I'm trying to prevent an edge case when somebody performs a POST request against my API UploadAppraisalFile endpoint and suddenly loses an internet connection which would result in sending a request with not the full file content.
My idea was to count the file size at the point where the file is uploaded, add the information about the file size as an extra HTTP-HEADER (I called it Complete-File-Size), and then when the request reaches the backend, count if the received file size is exactly the same as the Complete-File-Size.
To produce such an issue/edge case I tried:
uploading a big file(about 16MB) and then suddenly after submitting the HTML form immediately close the browser window.
uploading a file and then, in the Chrome browser, in the Network pane, change the uploading speed to a very minimum, then submit the form and then immediately close the browser.
When I run the debug mode, in each case I found that either: UploadAppraisalFile endpoint was never reached or if it was reached then always the full file was sent. For the 2nd successful case, to be 100% sure I converted the received file into base64 string and then I checked how the file looks like in https://codebeautify.org/base64-to-image-converter.
My question is: Is it even possible that the sent POST request is broken and contains not full file content due to a broken internet connection that happened suddenly during the sending process? If yes, then what's the best way to produce the issue. Cheers
You can pass HttpContext.RequestAborted as a CancellationToken to ALL async methods provided by .NET in "some other logic" part.
Let's use code you provided as an example :
await stream.CopyToAsync(memoryStream, HttpContext.RequestAborted)
I don't have an access to a full method but I assume you save it to some blob storage or file system. Most of these persistence API's accept CancellationToken as a parameter.
Receiving incomplete file
I was able to achieve a "partial" file using this code and Postman. It will basically read chunks from response stream until connection is interrupted.
As soon as I close Postman window TaskCancelledException is raised and stream is closed.
[HttpPost]
public async Task<IActionResult> UploadAppraisalFile([FromForm] IFormFile file)
{
var appraisalfile = file ?? Request.Form.Files.FirstOrDefault();
if (appraisalfile != null)
{
var buffer = ArrayPool<byte>.Shared.Rent(1024);
using var stream = appraisalfile.OpenReadStream();
while (await stream.ReadAsync(buffer, 0, buffer.Length, HttpContext.RequestAborted) > 0)
{
// Do something with buffer
_logger.LogInformation("Total length (bytes) {0}, partial length (bytes) {1}", stream.Length, stream.Position);
}
ArrayPool<byte>.Shared.Return(buffer);
}
return Ok();
}

Azure encoding job via REST Fails

I am trying to upload a video and encode it via azure rest service.
I have now hit the step of encoding the video but I am having difficulties with the request.
The following code shows my request:
var joburl = res.RequestMessage.RequestUri + "Jobs";
client = new HttpClient();
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer " + token);
client.DefaultRequestHeaders.Add("x-ms-version", "2.8");
client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0");
client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0");
client.DefaultRequestHeaders.Add("x-ms-date", date);
//accept
t = new NameValueHeaderValue("odata", "verbose");
type = new MediaTypeWithQualityHeaderValue("application/json");
type.Parameters.Add(t);
client.DefaultRequestHeaders.Accept.Add(type);
result = await client.PostAsync(joburl,json);
the url:https://wamsamsclus001rest-hs.cloudapp.net/api/Jobs
the json:
{"Name":"khgfiuydencodingjob","InputMediaAssets":[{"__metadata":{"Uri":"https://wamsamsclus001rest-hs.cloudapp.net/api/Assets('nb%3acid%3aUUID%3ad037b321-cd1c-43a9-9607-c4910fa7a85b')"}}],"Tasks":[{"Configuration":"H264 Adaptive Bitrate MP4 Set 720p","MediaProcessorId":"nb:mpid:UUID:1b1da727-93ae-4e46-a8a1-268828765609","TaskBody":"<?xml version=\"1.0\"encoding=\"utf-8\"?><taskBody><inputAsset>JobInputAsset(0)</inputAsset><outputAsset>JobOutputAsset(0)</outputAsset></taskBody>"}]}
The bearer token works as I use it for other request.
But I get a bad request 400 with the followin error message:
{"error":{"code":"","message":{"lang":"en-US","value":"Parsing request content failed due to: Make sure to only use property names that are defined by the type"}}}
Can anyone spot the error.
Thank you for the help
Okay I got it to work. Needed a odata=verbose in my json/string content - like this:
var jobInJson = JsonConvert.SerializeObject(job);
json = new StringContent(jobInJson, Encoding.UTF8);//,
json.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
I tried this earlier however I got a error 500 but now it is working.