I've tried to find a solution for this, but all the ones coming up are for previous versions of ASP.Net.
I'm working with the JWT authentication middleware and have the following method:
private async Task GenerateToken(HttpContext context)
{
var username = context.Request.Form["username"];
var password = context.Request.Form["password"];
//Remainder of login code
}
This gets the sent data as if it was form data, but my Angular 2 front end is sending the data as JSON.
login(username: string, password: string): Observable<boolean> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify({ username: username, password: password });
return this.http.post(this._api.apiUrl + 'token', body, options)
.map((response: Response) => {
});
}
My preferred solution is to send it as JSON, but I've been unsuccessful in retrieving the data. I know it's sending, because I can see it in fiddler, and if I use Postman and just send form data it works fine.
Basically I just need to figure out how to change this line to read the json data
var username = context.Request.Form["username"];
By the time it gets to your middleware the request stream has already been read, so what you can do here is Microsoft.AspNetCore.Http.Internal.EnableRewind on the Request and read it yourself
Site wide :
Startup.cs
using Microsoft.AspNetCore.Http.Internal;
Startup.Configure(...){
...
//Its important the rewind us added before UseMvc
app.Use(next => context => { context.Request.EnableRewind(); return next(context); });
app.UseMvc()
...
}
OR selective :
private async Task GenerateToken(HttpContext context)
{
context.Request.EnableRewind();
string jsonData = new StreamReader(context.Request.Body).ReadToEnd();
...
}
Related
I have code to allow us to use the NetSuite REST API using OAuth 1.0. Everything works fine, except one call. When trying to do /salesorder/{id}/!transform/itemFulfillment It fails with 401. All other calls work fine. When I execute the same call from Postman it works fine too. What am I missing?
Here is my Code:
private static async Task CreateItemFulFillmentsAsync(NetSuiteJob job, int id, Item item)
{
RestRequest request = new RestRequest($"{job.RecordUrl}/salesorder/{id}/!transform/itemFulfillment", Method.Post);
request.AddBody(item);
RestHelper restHelper = new RestHelper();
RestResponse response = await restHelper.ExecuteRestRequest(request, job);
if (response == null || !response.IsSuccessful)
{
throw new Exception($"Failed to create the Item Fulfillment for the Sales Order: {id}.\r\n" + response.Content);
}
}
And the Helper Class:
public async Task<RestResponse> ExecuteRestRequest(RestRequest request, NetSuiteJob job)
{
RestClient client = new RestClient(job.BaseUrl) { Authenticator = GetOAuth1Authenticator(job) };
RestResponse response = await client.ExecuteAsync(request);
return response;
}
private OAuth1Authenticator GetOAuth1Authenticator(NetSuiteJob job)
{
OAuth1Authenticator oAuth1 = OAuth1Authenticator.ForAccessToken(
consumerKey: job.ConsumerKey,
consumerSecret: job.ConsumerSecret,
token: job.TokenId,
tokenSecret: job.TokenSecret,
OAuthSignatureMethod.HmacSha256);
oAuth1.Realm = job.Realm;
return oAuth1;
}
The results are:
{"type":"https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2",
"title":"Unauthorized","status":401,
"o:errorDetails":[{"detail":"Invalid login attempt. For more details,
see the Login Audit Trail in the NetSuite UI at Setup > Users/Roles
> User Management > View Login Audit Trail.","o:errorCode":"INVALID_LOGIN"}]}
In NetSuite's Login Audit Trail, this call is logged as a failure and Role is blank, but the other calls using different action shows the Role like it should. The working routines use the same helper class but are doing it with a different URL and Body. I've verified the content being passed matches what I did manually in Postman too.
I am new to react and web api and I am getting this unsupported media type error while trying to upload my file into my web api function
Here is my react js code:
onFileUpload = () => {
// Create an object of formData
const formData = new FormData();
console.log("FormData");
// Update the formData object
formData.append('myFile', this.state.selectedFile, this.state.selectedFile.name);
console.log(this.state.selectedFile);
// Request made to the backend api
// Send formData object
//axios.post("api/uploadfile", formData);
axiosAPI.post('api/observation/Uploadfile', formData).then(response => {});
};
The corresponding web api code is this:
[HttpPost]
[Route("Uploadfile")]
public IHttpActionResult Uploadfile(object formData)
{
try
{
return Ok(formData);
}
catch (Exception ex)
{
return Content(HttpStatusCode.NoContent, "Something went wrong");
}
}
I am trying to upload the file and get it to my backend however I am getting this error. What does this error mean and how do I resolve this?
I had the same issue, I'm using .NET 6 for the API and React with Axios for the frontend.
To be able to get the file in the controller, I had to use the "FromForm" attribute, otherwise, I was getting the 415 error when I tried to do the Post Request.
[HttpPost]
public async Task<IActionResult> Create([FromForm] ExampleDto dto)
{
/// ...
}
To send the data from the React Application using Axios, I just created the FormData object just like you did, and made a post request without any special headers o configuration.
Hope this can help you solve your issue.
Whenever you are uploading a file, make sure to add appropriate headers to the request.
axiosAPI.post('api/observation/Uploadfile', formData, {
headers: {
'Content-Type': 'multipart/form-data' // <- HERE
}
}).then(response => {});
Sometime the issue is on formData, you need to append file obj on formData then send to api.
const formData = new FormData();
var file = fileList[0].originFileObj;
formData.append("excelFormFile", file); //Append file obj to formData
//excelFormFile name similar to .NET Core Api Like
c# Code : ' public async Task PostProductImport(IFormFile excelFormFile) '
I've done a post method using Axios to upload images using ImagePicker in React-Native but when I send this request to the API Post with my FormData it appears to me the 400 error
Possible Unhandled Promise Rejection (id: 0): Error: Request failed
with status code 400
But when I use the Upload variable instead of the FormData I created it sends the request to my API but no data
I already used the post method to log in and it works with password and user enter the API and I get the right values
const response = await api.post("Usuarios/FindByEmailSenha", {
email: this.state.email,
pass: this.state.pass
});
Client Side
handledUpload = () => {
ImagePicker.launchImageLibrary({}, async upload => {
const arquivo = new FormData();
arquivo.append('file', {
uri: upload.uri,
type:upload.type,
name: upload.fileName
});
var fotos = {
Id: 1,
IdUsuario: 1,
NumCode: 4
}
api.post(`galeria/UploadArquivos/`, arquivo, fotos);
})
};`
Server Side
[HttpPost]
[Route("UploadArquivos")]
[Consumes("application/json", "application/json-patch+json", "multipart/form-data")]
public IEnumerable<Galeria> UploadArquivos(IFormFileCollection arquivo, Galeria fotos)
{
}
I hope to receive FormData data sent from React-Native to my API so I can debug and be saving on the server
I'm trying to implement a simple push notification mechanism for a webpage. So I created a WebAPI controller with a method like this:
[HttpGet]
public HttpResponseMessage Subscribe()
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new PushStreamContent(
(stream, headers, context) => OnStreamAvailable(stream, headers, context),
"text/event-stream"
);
return response;
}
But when I try to call it from the client code:
function listen() {
if (!!window.EventSource) {
const server = new EventSource('http://localhost:5000/api/Notifications/');
server.addEventListener('message', function (e) {
const json = JSON.parse(e.data);
console.log('message', json);
});
server.addEventListener('open', function (e) {
console.log('open');
});
server.addEventListener('error', function (e) {
if (e.readyState === EventSource.CLOSED) {
console.log('error');
}
});
}
}
Chrome replies me with an: EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection.
I have to add that the code I'm writing is based on this tutorial (which uses MVC5).
My question is: How can I make the Subscribe method work? Thanks in advance.
Trying to pass a payload via Typescript service to an http.post
My .ts code:
saveEdits(body: Object): Observable<Animal[]> {
let bodyString = JSON.stringify(body);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.UrlToEdit, body, options)
.map((res: Response) => res.json())
.catch((error: any) => console.log("Edited value did not been saved"));
}
Mention that
private UrlToEdit = '/Home/Edit';
Although the value is up to the service, C# controller not seems to fire up.. An here its code:
[HttpPost]
public async Task<Boolean> Edit([Bind(Include = "animalID,animalName,animalHabitat,animalClass")] Animal animal)
{
if (ModelState.IsValid)
{
db.Entry(animal).State = EntityState.Modified;
await db.SaveChangesAsync();
return true;
}
return false;
}
I dont know how your whole site is working but maybe this helps you:
First i see an error in your code, you should pass the bodyString in the post not the body
return this.http.post(this.UrlToEdit, bodyString, options)
.map((res: Response) => res.json())
.catch((error: any) => console.log("Edited value did not been saved"));
Second post returns an Observable so the post is executed when something subscribes to the observable like this
//...somewhere in your code ...
service.saveEdits(body).subscribe((animals: Animal[]) => console.log(animals));
Also open chrome debugger (or whatever browser you use) and see in the network tab if the post is executed and if there is any error
I hope this helps you