.net core web api upload file fail with badrequest - asp.net-core

I am trying to upload several files to a web api endpoint with .net core 2.1 web api
this is my controller and the method to upload
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class PagosController : ControllerBase{
[HttpPost("UploadDescuento")]
public async Task<IActionResult> UploadDescuento(IEnumerable<IFormFile> files)
{
return Ok();
}
}
with postman i made a request to de controller but i am getting a badrequest
the first time I thought my request is bad so i do the same request in postman
POST /api/pagos/UploadDescuento HTTP/1.1
Host: localhost:59039
User-Agent: PostmanRuntime/7.16.3
Accept: */*
Cache-Control: no-cache
Postman-Token: 7535f283-89fb-4f86-bbb9-3d78ec302ebe,19a709dd-37c9-48ef-a157-c21f99861260
Host: localhost:59039
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Accept-Encoding: gzip, deflate
Content-Length: 1320022
Connection: keep-alive
cache-control: no-cache
Content-Disposition: form-data; name="files"; filename="/C:/Users/jcpc9/Pictures/0-5616x3744.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--,
Content-Disposition: form-data; name="files"; filename="/C:/Users/jcpc9/Pictures/0-5616x3744.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="files"; filename="/C:/Users/jcpc9/Pictures/101-2621x1747.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="pago"
234235834
------WebKitFormBoundary7MA4YWxkTrZu0gW--
but im getting badrequest
{
"": [
"The input was not valid."
]
}

my solution was remove de attribute ApiController i dont know why the documentation doesnt say to much [https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-2.2#multipartform-data-request-inference] i dont understend what is the problem
[Produces("application/json")]
[Route("api/[controller]")]
//[ApiController]<<remove this
public class PagosController : ControllerBase
and the method
[HttpPost("UploadDescuento")]
public async Task<IActionResult> UploadDescuento(IEnumerable<IFormFile> files)
if someone know why this propertie "[ApiController]" causing this problema i hope you can explain or at leas an good article

You're not uploading the file. You're just sending the path of the file on the client machine, which the server can't do anything with (unless the server and client machines will always be the same).
Postman does have the option of sending a file properly. See this answer.

You need to select form-data in the body in postman and set up a key "files" as file type example

Related

Spark Java - strange behavior when uploading files

In my project I want to try to upload files, here is the part of the code responsible for this:
MultipartConfigElement multipartConfigElement =
new MultipartConfigElement(
"/tmp_files",
avatarSize,
avatarSize,
1024
);
request.raw().setAttribute(
"org.eclipse.jetty.multipartConfig",
multipartConfigElement
);
Part uploadedFile = request.raw().getPart("file");
And a request to upload a file using Idea's http client:
POST http://localhost:8080/users/me/avatar
Content-Type: multipart/form-data; boundary=abcd
Authorization: Bearer {{authToken}}
--abcd
Content-Disposition: form-data; name="file"; filename="test.png"
< /Users/user1/resources/test.png
--abcd--
where test.png is a regular picture.
But when I try to load in this code place:
Part uploadedFile = request.raw().getPart("file");
I get an error:
java.nio.file.NoSuchFileException: /tmp_files/MultiPart11851484240893602177
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218)
at java.base/java.nio.file.Files.newByteChannel(Files.java:375)
at java.base/java.nio.file.Files.createFile(Files.java:652)
It can be assumed that this error is due to the fact that there are no write permissions to the root of the file system (I'm testing on mac os, under the user).
But if i try to upload another file - which is just a zip file then everything works.
POST http://{{host}}/users/me/avatar
Content-Type: multipart/form-data; boundary=abcd
Authorization: Bearer {{authToken}}
--abcd
Content-Disposition: form-data; name="file"; filename="file123.zip"
< /Users/18493151/develop/icandev/api-gateway/src/main/resources/file123.zip
--abcd--
and no exception in this line:
Part uploadedFile = request.raw().getPart("file");
Why is this happening? Why does the result depend on the file type?
sparkjava version 2.9.4

Unexpected token # in JSON at position 0 with Angular 5 and Express JS

I am developing a MEAN stack application
where My client is in Angular 5 and backend is in node and express js with mongo db as my storage.
I am trying to upload an image from one my Angular Page to my express js rest API which will finally upload the image in AWS cloud
Sample code for my Component is as below having two methods one onFileSelected which sets the selected file and the onUpload which invokes a service class method
private selectedFile:File=null;
onUpload(){
this.productCategoryService.
uploadProductCategoryImage(this.selectedFile).subscribe(
data=>{console.log("Upload success---"+data)},
err=>{console.log("Upload error ---"+err.message)});
}
onFileSelected(event){
this.selectedFile=event.target.files[0];
console.log("this.selectedFile---------"+this.selectedFile);
}
The service does a post call of rest service on express js.Code of my service class is as below
public uploadProductCategoryImage(selectedFile:File){
const formData = new FormData();
formData.append("userFile",selectedFile);
return this.http.post<any>
('http://localhost:3000/datastore/api/aws/api/file',formData);
}
My html page
<input type="file" (change)="onFileSelected($event)" name="userFile">
<button type="button" class="btn btn-success" (click)="onUpload()">
<span class="fa fa-upload"></span>Upload</button>
However when I post this data I get an error as below on the server side
SyntaxError: Unexpected token # in JSON at position 0
at JSON.parse (<anonymous>)
I found something from my browser.It shows BAD request.
I am not sure what is happening.Please suggest.
General------------
Request URL: http://localhost:3000/datastore/api/aws/api/file
Request Method: POST
Status Code: 400 Bad Request
Remote Address: [::1]:3000
Referrer Policy: no-referrer-when-downgrade
Response Header------------
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 1314
Content-Security-Policy: default-src 'self'
Content-Type: text/html; charset=utf-8
Date: Fri, 22 Jun 2018 16:47:12 GMT
X-Content-Type-Options: nosniff
X-Powered-By: Express
Request Header--------------------
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 232378
Content-Type: application/json
Host: localhost:3000
Origin: http://localhost:4200
Referer: http://localhost:4200/contactus
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36
------WebKitFormBoundaryAEgWhmyP5LdwDaEl
Content-Disposition: form-data; name="userFile"; filename="Screenshot from 2018-06-04 20-23-28.png"
Content-Type: image/png
Thanks
Sachin
In Angular 5 Httpclient uses JSON as default format. So you have use BLOB as your response type like
getImage(imageUrl: string): Observable<Blob> {
return this.httpClient.get(imageUrl, { responseType: 'blob' });
}
Check this link for reference: https://stackblitz.com/edit/angular-1yr75s?file=src%2Fapp%2Fimage.service.ts

how to set no content-type using apache httpclient

i am facing one issue on apache httpclient(the latest release)
i am using
builder.addPart("_sid", new StringBody("abcd"));
to build form part, but in server, the request info is:
Content-Disposition: form-data; name="_sid"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
i want the http client do not send the two lines:
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
is there any code could help me?
refer to In apache http client, how to keep the Content-Type in a StringBody as empty or null? , i get the key:
- FormBodyPart bodyPart = new FormBodyPart("_sid", new StringBody(sessionID, ContentType.DEFAULT_TEXT)) {
#Override
protected void generateContentType(ContentBody body) {
}
#Override
protected void generateTransferEncoding(final ContentBody body){
}
};

Resteasy destroys filename encoding on multipart/form-data POST requests

I do a fileupload to the following annotated Restservice
#POST
#Path("/uploadFile")
#Consumes("multipart/form-data")
public Response uploadFile(MultipartFormDataInput input)
When special characters in the filename like "äÄöÖüÜß" are used, the filename gets corrupted during processing of Resteasy subsystem.
I verified this by creating a Logginginterceptor
#Provider
#ServerInterceptor
public class LoggingInterceptor implements PreProcessInterceptor
Inside this interceptor, the http fileupload (multipart/form-data) is still correct
Content-Disposition: form-data; name="file"; filename="TestäÄöÖüÜßFile2.pdf"
Content-Type: application/pdf
when Resteasy calls the uploadFile Method, the filename is corrupted
Content-Disposition: form-data; name="file"; filename="Test��������������File2.pdf"
Content-Type: application/pdf
Is there a possibility (maybe by some annotation) to preserve the filename encoding in the Entity?
Kind regards
Shane

WebAPI 2 with OWIN middleware and token-based authentication: OPTIONS request returns "unsupported_grant_type" error

WEbAPI provides end-point for authentication request: http:\...\token
Authentication request should be sent using Method "POST" and Body like
"grant_type=password&username=name&password=mypassword"
This WebAPI is used by Front-End which is written using AngularJS.
Sometimes before sending "POST" request with valid Body, a "OPTIONS" request is sent without Body.
As result the following error is returned by WebAPI:
Status: 400
{"error":"unsupported_grant_type"}
Is there any solution which can be implemented on Server-side? (in WebAPI)
HTTP Request Method: OPTIONS
Request Header:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,de;q=0.6,ru;q=0.4,uk;q=0.2
Access-Control-Request-Headers:accept, authorization, content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Host:...
Origin:...
Pragma:no-cache
Proxy-Connection:keep-alive
Referer:...
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Response Header:
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 34
Content-Type: application/json;charset=UTF-8
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: *
X-Powered-By: ASP.NET
Date: Thu, 11 Sep 2014 18:05:09 GMT
I just ran into the same issue..I'm using ember and ember-simple-auth. Any preflight requests OPTIONS to the /token endpoint were resulting in a 400 HTTP response and the body had the well known: {error: "unsuported_grant_type"}.
SOLUTION:
I inherit from: OAuthAuthorizationServerProvider and override the MatchEndpoint function:
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
if (context.OwinContext.Request.Method == "OPTIONS" && context.IsTokenEndpoint)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Methods", new[] {"POST"});
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "accept", "authorization", "content-type" });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
context.OwinContext.Response.StatusCode = 200;
context.RequestCompleted();
return Task.FromResult<object>(null);
}
return base.MatchEndpoint(context); }
That seems to take care of it. Hope it helps.
I got the same error when I forgot to add Content-Type: application/x-www-form-urlencoded to the request header.
I was attempting to test my api with Fiddler and wasn't providing the data in the correct format in the Request Body section. Be sure it's added as a key value list separated by '&'.
grant_type=password&username=testUsername&password=testPassword
In this case OPTIONS is a CORS preflight request. It is sent in order to determine whether the actual request (POST) is safe to send. Cross-site requests are preflighted if uses methods other than GET, HEAD or POST or sets custom headers.
In order to avoid a 400 HTTP response, in your Startup class you should enable CORS for the OWIN middleware using UseCors extension method and define your custom System.Web.Cors.CorsPolicy.
using Microsoft.Owin.Cors;
using Microsoft.Owin.Security.OAuth;
using Owin;
namespace AuthorizationServer
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions()
{
});
}
}
}