Azure Function HTTP Multi-Part POST Not Recognizing Field - azure-logic-apps

I am trying to post to a web service using a multi-part form. However the service is saying it can't recognize the file upload I am trying to send. This is the section for the file upload.
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="GOO1242.pdf"
Content-Type: application/pdf
JVBERi0xLjQKJdP0zOE....... <rest of file>
----WebKitFormBoundary7MA4YWxkTrZu0gW
The error is
{
"type": "validation_error",
"detail": "There is no field: "file"."
}
Any ideas what is wrong?

Not sure if this is what you're looking for but I've used RestSharp to do this in a C# azure function
var apiRequest = await GetRestRequest(request);
var response = await SendRequest(apiRequest, log);
private async Task<RestRequest> GetRestRequest(string requestInput)
{
var uploadRequestInput = JsonConvert.DeserializeObject<UploadModelRequest>(requestInput);
var base64EncodedBytes = Convert.FromBase64String(uploadRequestInput.Content);
var uploadBicxRequest = JsonConvert.DeserializeObject<UploadModelRequest>(requestBody);
var apiRequest = new RestRequest("system/archive/document", Method.POST);
apiRequest.AddParameter("key", JsonConvert.SerializeObject(uploadRequest), "application/json", ParameterType.RequestBody);
apiRequest.AddFileBytes("VersionData", base64EncodedBytes, uploadRequest.PathOnClient, "application/octet-stream");
apiRequest.AddHeader("Content-Type", "multipart/form-data");
return apiRequest;
}

Related

Sending FormData to Spring boot rest API get bad request 400

I built my API using spring boot.
#RequestMapping(value = "/v1/users/profile-picture/update", method = RequestMethod.POST)
public Object updateProfilePicture(Principal principal, #ModelAttribute UpdateProfilePictureDTO profile_picture){
Long user_id = accessTokenHandler.getIdByPrincipal(principal);
if(user_id == null)
return new DefaultResponseDTO(201,ResponseStatus.INVALID_USER,"No such user.");
if(profile_picture.getProfile_picture() == null)
return new DefaultResponseDTO(201,ResponseStatus.MISSING_INPUTS,"Profile Picture is missing.");
return userService.updateProfilePicture(user_id, profile_picture.getProfile_picture());
}
I want to send an image file to this controller. I tried with react.js. First I build formData and append the image into form data.
let formData = new FormData()
formData.append(
'profile_picture',
newFileList[0],
)
React API end point,
export async function profilePictureUpdate(formData) {
//image must be send as formdata
const response = await http.post(
apiEndPoint + '/profile-picture/update',
formData,
{
headers: {
Authorization: `Bearer ${getJwt()}`,
"Content-type": "multipart/form-data",
}
});
console.log("response of profile picuter", response);
return response
}
But when submit an image file, get a 400 bad request. How can I solve this?
Spring Boot (2.4.x): replace #ModelAttribute UpdateProfilePictureDTO profile_picture with #RequestParam(value = "profile_picture") MultipartFile file and then process the file. Make sure MultipartAutoConfiguration enabled (docs). If you registered a servlet via ServletRegistrationBean add multipart config to it:
servletRegistrationBean.setMultipartConfig(new MultipartConfigElement("/tmp",
multipartProperties.getMaxFileSize(),
multipartProperties.getMaxRequestSize(),
multipartProperties.getFileSizeThreshold()));

Throwing error while downloading file in ASP.NET Core with status code 400

I'm working on download feature. When I run code on localhost, it runs perfectly without any error. But when I uploads same code to server then it returns Failed to load resource: the server responded with a status of 400 (Bad Request) error in console of browser. For requesting and getting response from server, I have used Axios. I'm newbie to ASP.NET Core + ReactJS technology stack and working on APIs for the first time so it's being difficult for me to figuring out root cause of this error.
Here is my code for requesting data from server.
axios({
method: 'POST',
url: '/api/ImageFetch/ImageFetchPoint',
responseType: 'blob',// important
headers: {
'Content-Type': 'application/json'
},
data: filepath
}).then(function(response) {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
}).catch(error => {
console.log("Status:", error.response.status);
console.log("Data:", error.response.data);
});
For getting response as file(any extension) from server, I've used following code.
[HttpPost("PanImageFunction")]
[Route("api/[controller]/[action]")]
public async Task<IActionResult> ImageFetchFunction([FromBody] ImageFetchRequest request)
{
var filePath = request.ImagePath;
var filename = System.IO.Path.GetFileName(filePath);
string path="unknownpath";
try {
if (filename == null)
return Content("filename not present");
path = Path.Combine(
Directory.GetCurrentDirectory(),
"RegistrationImages", filename);
} catch(Exception ex) {
new Logger().write(ex);
}
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = false // false = prompt the user for downloading; true = browser to try to show the file inline
};
Response.Headers.Add("Content-Type", "multipart/form-data");
Response.Headers.Add("Content-Disposition", cd.ToString());
Response.Headers.Add("X-Content-Type-Options", "nosniff");
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
private string GetContentType(string path)
{
var types = GetMimeTypes();
var ext = Path.GetExtension(path).ToLowerInvariant();
return types[ext];
}
private Dictionary<string, string> GetMimeTypes()
{
return new Dictionary<string, string>
{
{".txt", "text/plain"},
{".pdf", "application/pdf"},
{".doc", "application/vnd.ms-word"},
{".docx", "application/vnd.ms-word"},
{".xls", "application/vnd.ms-excel"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"},
{".csv", "text/csv"}
};
}
Complete code works perfectly on localhost. But when I uploads it on server then it throws 400 bad request error on console of browser as you can see in following image.
I have checked many forums and articles but most of the articles related to ASP.NET core giving solution related to Razor pages and not giving solutions related to ReactJS and Axios.
How can I fix this error?

JSON POST request sends only id

Hello Everyone I couldn't find any solution so here is my question
I tried to write POST Request and tried to POST data as JSON, it works
but I only get new Object in JSON file with new ID, nothing else is being sent.
This is ReaactJS app to be exact
var url = 'http://localhost:3000/applications'; //Configurable endpoint
var request = new XMLHttpRequest();
var isSent = false;
var data = {
name : this.state.name,
age : this.state.age,
prefix : this.state.prefix,
email : this.state.email
}
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function () {
isSent = true;
console.log(this.responseText);
};
xhr.send(data);
This is my way to do so
You should check out new fetch API.
The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to anyone who has used XMLHttpRequest, but the new API provides a more powerful and flexible feature set.
Please check Fetch: POST json data
The problem night be with the formatting of the .rest file
For example
POST http://localhost:3001/api/persons
Content-Type: application/json
{
"name" : "fbgjdbh",
"number" : 89475947
}
this worked for me. You need to leave an empty line after the content-type, then specify the object.
The following was not working for me and was only sending the id.
POST http://localhost:3001/api/persons
Content-Type: application/json
{
"name" : "fbgjdbh",
"number" : 89475947
}

Unable to Download xlsx on client side using Filesaver.JS in React

I tried the previous solutions on stackoverflow as well as other options including defining responseType as "arraybuffer" and "blob", I'm not able to download xlsx file generated on the client side. The repsonse.data is in the form of byte[].
I see that the file has contents, but when I try to open it, it says - "The file format or file extension is not valid "
UI Snippet:
axios.post('/api/report/generateReport', {}, {
params: {
reportId: this.state.reportId,
lob: this.state.lob
}
}, {responseType: 'arraybuffer'})
.then(function (response) {
var blob = new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
FileSaver.saveAs(blob, 'Metrics.xlsx');
})
Backend Snippet
#POST
#Path("/generateReport")
public Response generateReport(#QueryParam("reportId") int reportId, #QueryParam("lob") String lob) {
Response response = null;
byte[] contents = null;
contents = metricsReport.generateReport(lob);
response = Response.status(Response.Status.OK).entity(contents).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Content-Disposition", "attachment; filename=Metrics.xlsx").allow("OPTIONS")
.build();
return response;
}
I think you need to set content-type to application/octet-stream in the response from the server.
Something like(spring boot)-
return ResponseEntity.ok().contentLength(file.contentLength())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header("Content-disposition", "attachment; filename=Metrics.xlsx")
.body(inputStreamResource)

Unable to download Excel spreadsheet with outputstream data from backend

The REST method to return outputStream data to download an Excel spreadsheet:
#RequestMapping(value = "/downloadxls", method = RequestMethod.GET)
public #ResponseBody void getRecordsAndExportExcel(#RequestParam("search_param") String students, HttpServletResponse response) {
response.setContentType("application/vnd.ms-excel");
Workbook hssfWorkbook = exportExcelService.getExcelStudents(students);
try {
OutputStream out = response.getOutputStream();
hssfWorkbook.write(out);
out.flush();
out.close();
} catch (IOException e) {
logger.error("Error exporting to excel:" + e);
}
}
I am getting the data as bytes, but in Angular I am trying to present it as an Excel spreadsheet; but it won't download. I am doing this for the conversion:
var blob = new Blob([result.data], {type : 'application/vnd.openxmlformats-officedocument.presentationml.presentation;charset=UTF-8'});
FileSaver.saveAs(blob, "MyData.xls");
The request and response headers:
Access-Control-Allow-Headers:x-requested-with, content-type
Access-Control-Allow-Methods:GET OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Content-Type:application/vnd.ms-excel;charset=UTF-8
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
X-Application-Context:application:8080
Request Headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ms;q=0.6
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:9000
Referer:http://localhost:9000/
I am making a GET-call from frontend using Angular and calling backend to download the data as an Excel spreadsheet, but it is not able to convert the output stream to blob/excel. How can I present an Excel spreadsheet as download?
The way I would present an excel sheet in my application is to return the path+filename of the excel sheet to show and then open the link using angular in a new tab.
In the service class
ExportExcel response = new ExportExcel();
response.setPath(excelPath);
return response;
Controller class
Response response = excelService.generateExcel();
return new ResponseEntity<>(response, HttpStatus.OK);
In your angular controller:
if(response.status === 200){
var excelPath = response.data.path;
var win = window.open(excelPath, '_blank');
if (win) {
//Browser has allowed it to be opened
win.focus();
} else {
//Browser has blocked it
swal(
"Error!",
'Please allow popups for this website',
"error"
);
}
}
Try and see if this works.

Resources