I have a problem that has been going on for over a month now, I've tried everything I know about react and .net core, so I thank anyone who helps me. I need to send a formdata and other parameters to the api as a foreign key, but I can't find a viable solution.
here is my .net action to insert data
[HttpPost]
public async Task<IActionResult> AdicionarCandidato([FromForm]AddCandidatoDTO candidato, Guid classe, Guid curso, Guid ano, Guid periodo)
{
try
{
// candidato.DescricaoFoto = Upload(candidato.FileFoto).ToString();
await _inscricao.Adicionar(candidato, classe, curso, ano, periodo);
await _inscricao.Persistir();
return Created();
}
catch(Exception ex)
{
return BadRequest($"Erro ao inserir candidato: {ex.Message}");
}
}
next the react redux funtion to send data
export const insertInscrito = async (dispatch, candidato, classe, curso, ano, perido) => {
dispatch(actionCreators.reqInsertInscrito());
try {
// api request
const { data } = await axios.post(baseUrl, candidato +classe +curso +ano +perido)
dispatch(actionCreators.insertInscrito(data));
} catch (error) {
dispatch(actionCreators.errorInsertInscrito(error.message));
}
}
then the form page with inputs and methods
const handleFormSubmit = e => {
e.preventDefault();
let formData = new FormData();
formData.append('Nome', selectedCandidato.Nome);
formData.append('Sobrenome', selectedCandidato.Sobrenome);
formData.append('NomePai', selectedCandidato.NomePai);
formData.append('NomeMae', selectedCandidato.NomeMae);
formData.append('DataNascimento', selectedCandidato.DataNascimento);
formData.append('Rupe', selectedCandidato.Rupe);
formData.append('NumeroBilhete', selectedCandidato.NumeroBilhete);
//formData.append('TextoFoto', selectedCandidato.TextoFoto);
formData.append('Sexo', selectedCandidato.Sexo);
formData.append('EstadoCivil', selectedCandidato.EstadoCivil);
formData.append('Email', selectedCandidato.Email);
formData.append('Telefone', selectedCandidato.Telefone);
formData.append('Provincia', selectedCandidato.Provincia);
formData.append('Municipio', selectedCandidato.Municipio);
formData.append('Rua', selectedCandidato.Rua);
insertInscrito(dispatch, formData
+ selectedCandidato.ClasseId
+ selectedCandidato.CursoId
+ selectedCandidato.AnoLectivoId
+ selectedCandidato.PeriodoId)
}
First I tried to change the formdata to normal text and then I tried to transform each parameter as an element of the formdata, but the api still does not recognize the other parameters.
Please try to install npm i axios and then
send requests using the package as below
const axios=require('axios');
const submitForm=async ()=>
{
const {data}=await axios({
withCredentials: true,
url:'your endpoint will be here',
method:'post',
data: selectedCandidato,
headers:{
Authorization:'api token'
}
}).then(response=>{
return response;
}).catch(error=>{
return error;
});
console.log('request sent -> ',data);
}
Related
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) '
After registration user get a link, which consist of userId and token. When user click on it - angular project opens, then angular takes userId and token from link, and send a post method to backend for verifying email.
Link example
http://localhost:4200/user/confirmemail/?userId=9bc9a474-d10c-438b-8953-1c32fc57551b&token=Q2ZESjhPRkF6d3BPQ1E5TmtLbWplTnlIZ3g3bzJEVEZQZDQ3MFNSblExaWxBTWh3MmdSMWl2ZkU3djZxcWR3bmY4OFMwd2l6STZOY3VMR2FoZ1ZCM28rWFo1YlJhejhOTE5pamFFdGRETTNiNGttT0lOQ2dZVmdLRVlRdWlKRmtQMVpEWHE0b2t2NVBQZTZ0bkR3cUdrb3JiMWRIQUpRUE5pMTZjTW96YUdJcVZBUUxPSG5pd3NDU3BDeTBNREMvMTVyTlhUNUpCL2tRZTJWMjJlTzVHZ1dDbEh5VWNESGNsNlVTQkpXZ1FJaThDTk1kcUovcmdtV0ZEdEQza2hXR1p6V0pEdz09
Post method, which verify email:
[HttpPost("confirmEmail/{userId}")]
public async Task<IActionResult> ConfirmEmail(string userId, [FromBody]string token)
{
var codeDecodedBytes = WebEncoders.Base64UrlDecode(token);
var codeDecoded = Encoding.UTF8.GetString(codeDecodedBytes);
var user = await _userManager.FindByIdAsync(userId);
var result = await _userManager.ConfirmEmailAsync(user, codeDecoded);
return Ok(result);
}
It works fine in postman:
Error in Angular project:
Getting userId and token in Angular
userId: string;
token: string;
constructor(private activatedRoute: ActivatedRoute, private authService: AuthService) {
this.activatedRoute.queryParams.subscribe(params => {
this.userId = params['userId'];
this.token = params['token'];
});
}
ngOnInit(): void {
this.confirmEmail();
}
confirmEmail(){
this.authService.confirmEmail(this.userId, this.token).subscribe(data => { console.log("success")});
}
(AuthService) Sending data to backend
confirmEmail(userId: string, token: string){
console.log(userId);
console.log(token);
return this.http.post(this.authUrl + `confirmemail/${userId}`, token);
}
Try to set Content-Type to json type:
confirmEmail(userId: string, token: string) {
const body = JSON.stringify(token);
const options = {
headers: new HttpHeaders().append('Content-Type', 'application/json')
};
return this.http.post(this.authUrl + `confirmemail/${userId}`, body, options)
.pipe(
map(res => res)
, catchError(this.handleError())
);
}
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.
I have the following web server method, that returns data to our front-end applicaiton.
[FunctionName("SearchCustomerBySearchTerm")]
public static async Task<HttpResponseMessage> SearchCustomerBySearchTerm([HttpTrigger(AuthorizationLevel.Function, WebRequestMethods.Http.Get, Route = "Customer/SearchCustomerBySearchTerm/{searchTerm}/pageSize/{pageSize}")]HttpRequestMessage req, TraceWriter log, string searchTerm, int pageSize)
{
try
{
var continuationToken = req.Headers.TryGetValues("continuationToken", out IEnumerable<string> values) ? values.FirstOrDefault() : null;
PagedResponse<CustomerSearchResult> pagedResponse = await _customerComponent.FindCustomerBy(searchTerm, continuationToken, pageSize);
if (pagedResponse == null) return req.CreateResponse(HttpStatusCode.NoContent, $"Could not find any data related to {searchTerm}");
HttpResponseMessage responseMessage = req.CreateResponse(HttpStatusCode.OK, pagedResponse.Results);
responseMessage.Content.Headers.Add("continuationToken", pagedResponse.Continuation);
responseMessage.Content.Headers.Add("Access-Control-Expose-Headers", "*");
return responseMessage;
}
catch (Exception ex)
{
log.Error(ex.Message);
return req.CreateResponse(HttpStatusCode.InternalServerError, "Something went wrong. Could not search for customers");
}
}
I am allowing all headers to be exposed, by adding the Access-Control-Expose-Headers.
From my Angular application, I am doing the request as follow:
searchCustomersPaged(searchTerm: string, continuationToken: string): Observable<HttpResponse<CustomerSearchResult>> {
let customHeaders = new HttpHeaders().set("continuationToken", this.currentContinuationToken);
const url = "http://localhost:7071/api/Customer/SearchCustomerBySearchTerm/andrew/pageSize/10";
const parsedUrl = encodeURI(url);
return this.http.get<HttpResponse<CustomerSearchResult>>(parsedUrl, { headers: customHeaders });
}
As you can see above, I am expecting an HttpResponse<CustomerSearch> back.
Here is how I try and read my headers:
nextClikcedHandle(continuationToken: string): void {
this.customerService.searchCustomersPaged(this.customerService.searchTerm, this.currentContinuationToken)
.subscribe(resp => {
//add current continuation token, to previous now, as this will be used for 'previous' searching
this.previousContinuationTokens.push(this.currentContinuationToken);
//set next continuation token received by server
this.currentContinuationToken = resp.headers.get('continuationToken');
//return search results
this.customerService.searchResults.next(resp.body);
});
}
With the above code, the resp.headers and the resp.body is always undefined. Why is this happening?
If I look at the Network tab within Chrome, I can see my data is returned, as well as my header.
What am I doing wrong?
I found a useful article here:
By default the HttpClient returns the body of the response. You can
pass-in an object with an observe key set to a value of ‘response’ to
get the full response. This can be useful to inspect for certain
headers:
So I changed my code as follow, with the added observe key.
searchCustomersPaged(searchTerm: string, continuationToken: string): Observable<HttpResponse<CustomerSearchResult>> {
let customHeaders = new HttpHeaders().set("continuationToken", this.currentContinuationToken);
const url = "http://localhost:7071/api/Customer/SearchCustomerBySearchTerm/andrew/pageSize/10";
const parsedUrl = encodeURI(url);
return this.http.get<CustomerSearchResult>(parsedUrl, { headers: customHeaders, observe: 'response' });
}
After changing above method, I could query body and headers as per normal:
nextClikcedHandle(continuationToken: string): void {
this.customerService.searchCustomersPaged(this.customerService.searchTerm, this.currentContinuationToken)
.subscribe(resp => {
//add current continuation token, to previous now, as this will be used for 'previous' searching
this.previousContinuationTokens.push(this.currentContinuationToken);
//set next continuation token received by server
this.currentContinuationToken = resp.headers.get('continuationToken');
//return search results
this.customerService.searchResults.next(resp.body);
});
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();
...
}