Why am I getting null body values on my api request? - .net-core

Context:
It's a .Net Core app
Using React, Redux, and Axios which finally makes the request.
Axios call:
// At this point I do have values on my request
// { "param1": 2021, "param2": "where the sidewalk ends" }
console.log(myRequest);
axios.post('api/myPath/create', myRequest, options)
.then(function (result) {
...
})
.catch(function (error) {
...
});
Api controller:
namespace myNamespaceApi
{
[Route("api/myPath/create")]
[ApiController]
public class MyCreateController : .....
{
[HttpPost]
[Authorize(Policy = ShouldBeCertainRole)]
public async Task<MyApiOperationResult<MyCreateResponseViewModel>> Post([FromBody] MyCreateRequestViewModel request)
{
try
{
.....
// at this point my request comes with null values
// { "param1": null, "param2": null }
}
catch (Exception ex)
{
....
}
}
}
}
So it is making the call, but not reaching the method with the values.
Any suggestions?

Related

Response for preflight has invalid HTTP status code 405 with asp.net web api and Angular 2

i was trying to integrate my asp.net web api with angular 2.for checking login credential in a basic way.
asp.net web api code is
public void postvalidUser(string UserName, string Password)
{
try
{
var login = uData.Users.Where(x => x.UserName == UserName).ToList();
if (login != null && login.Count > 0)
{
foreach (var log in login)
{
if (log.UserName == UserName && log.Password == Password)
{
Console.WriteLine("login ok");
}
}
}
else
{
Console.WriteLine("login fail");
}
}
catch (Exception ex){
Console.WriteLine(ex);
}
}
login.service.ts file is as:-
#Injectable()
export class LoginService {
constructor(private _http: Http) { }
postvalidUser(UserName: string, Password: string) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({headers: headers });
const users = { UserName: UserName, Password: Password };
return this._http
.post("http://localhost:65440/api/User", users, options)
.map(result => result.json());
}
}
login.component.ts
export class LoginComponent implements OnInit {
constructor(private _loginservices: LoginService) { }
ngOnInit() {
}
OnClick(UserName: string, Password:string) {
this._loginservices.postvalidUser(UserName, Password).subscribe(users => console.log(users));
}
}
now when i m running my app it showing me the error as
Failed to load "my-url": Response for preflight has invalid HTTP status code 405 && OPTIONS "my-url" 405 (Method Not Allowed)
Please tell me whether my code is wrong or something is missing.
You have to authorize the OPTIONS requests in your backend.
The same way you authorize GET, POST and PUT requests, simply add OPTIONS to that list.
OPTIONS are, as stated, preflight requests sent by your browser to check the endpoints.
Your browser is sending off an OPTIONS request.
You need to either create a HttpOptions endpoint with the same route, or create a middle ware that intercepts all HttpOptions requests and returns a 200.

ASP.NET return null or no connection from angular4

I am trying to send JSON string from angular to asp.net server. I tried two things to get this data from client side.
1st : I have following code from both server and client side. I am sending a json string, and I expected to receive at backend for what I sent. However, I am just getting this server error before even getting the data.
POST "url" 404 (not found)
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:61476/api/testAPI/getData'.","MessageDetail":"No action was found on the controller 'getData' that matches the request."}
2nd : given that everything is same, i just added [FromBody] in my method like below. This doesn't return any server error and I am able to connect from my client side to server. However, I am getting my body message as null . I tried with Postman, but it seems that it works fine with Postman when I send same data.. I am aware that I can create some modelling in server code to match with my json string from client side, but I don't get why this doesn't work without modelling and also why connection fails without [FromBody].
All I need is to get JSON string from my client side. Can anyone please provide me advice on this?
public string getData([FromBody] string body)
angular
callServer(){
var json = {"name":"John Doe", "school": "A"};
let headers = new HttpHeaders();
headers.set('Content-Type', 'application/json');
this.appService.http.post('http://localhost:61476/api/testAPI/getData',
json,
{headers: headers})
.subscribe(data => {console.log(data), (err) => console.error("Failed! " + err);
})
}
server
namespace test.Controllers
{
public class testAPIController : ApiController
{
//
[HttpPost]
public string getData(string body)
{
try
{
Log.Info(string.Format("data {0}", body));
return "ok";
}
catch (Exception ex)
{
Log.Error(ex.Message);
return "error";
}
}
}}
Controller:
[HttpPost]
public string postData([FromBody]string body)
{
try
{
Log.Info(string.Format("data {0}", body));
return Json("ok");
}
catch (Exception ex)
{
Log.Error(ex.Message);
return "error";
}
}
Calling the server:
callServer() : Observable<string> {
var json = {"name":"John Doe", "school": "A"};
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
let apiUrl = 'http://localhost:61476/api/testAPI/postData';
return this.appService.http.post(`${this.apiUrl}`, json, options)
.map((res: Response) => res.json())
.catch(this.handleErrorObservable);
}
private handleErrorObservable(error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.message || error);
}
Calling the service:
this._service.callServer()
.subscribe(
res => { console.log(res) },
err => { console.log(err) }
)
console.log(res/err) will be your response from the POST call. Sorry if misinterpreted your question but your question is a little hard to follow.
404 error is "not found". You must decorate your API Class
[Route("api/TestApi/[action]")]
public class testAPIController : ApiController
{
[HttpPost]
[HttpPost, ActionName("getData")]
public string getData([FromBody]string body)
{}
}

Registering onError Callback on RxJS Observable causing same http request to be sent twice in Angular 2

I have created a HTTP Interceptor in Angular 2. The code of the interceptor is below
export class HttpInterceptor extends Http {
private httpSubject = new Subject<Message>();
httpSubject$ = this.httpSubject.asObservable();
private block : boolean = true;
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private dataSharingService : DataSharingService) {
super(backend, defaultOptions);
}
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.dataSharingService.beforeRequest.emit("beforeRequestEvent");
return this.intercept(super.post(url, body, this.getRequestOptionArgs(options)));
//return super.post(url, body, this.getRequestOptionArgs(options));
}
put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.dataSharingService.beforeRequest.emit("beforeRequestEvent");
return this.intercept(super.put(url, body, this.getRequestOptionArgs(options)));
}
getRequestOptionArgs(options?: RequestOptionsArgs) : RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
//options.headers.append('Content-Type', 'application/json');
return options;
}
intercept(observable: Observable<Response>): Observable<Response> {
observable.subscribe(
null,
error => this.dataSharingService.afterRequest.emit("afterRequestEvent"),
() => this.dataSharingService.afterRequest.emit("afterRequestEvent")
);
return observable;
}
}
In the intercept function if error callback is registered, browser makes same http requests twice, and when the error callback is removed then event is not fired (which is needed to hide loading indicator).
By error call back I mean this line
error => this.dataSharingService.afterRequest.emit("afterRequestEvent")
in the intercept method.
It seems the subject is registering subscribe() multiple times. Could you try unsubscribing the observable once the response through observable is returned back? Else, you may go for simpler way of creating a new observable during every intercept() call and return it instead to avoid multiple callbacks being registered.

Angular2 with ASP.NET Core CORS issues when sending POST request

Having issues when sending a POST request via my Angular 2 service to an ASP.NET Core API. I am currently getting a HTTP 500 error:
"XMLHttpRequest cannot load http://localhost:51014/api/sites. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500."
I am not getting this error on GET requests and as far as I can see I have CORS setup correctly server side?
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddCors();
services.AddMvc();
....
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseCors(builder =>
builder.WithOrigins("http://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod());
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
SitesContoller.cs
// POST: api/Sites
[HttpPost]
public async Task<IActionResult> PostSite([FromBody] Site site)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.Sites.Add(site);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (SiteExists(site.Id))
{
return new StatusCodeResult(StatusCodes.Status409Conflict);
}
else
{
throw;
}
}
return CreatedAtAction("GetSite", new { id = site.Id }, site);
}
My Angular 2 service:
site.service.ts snippet
public createSite(site: Site): Observable<Site> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify(site);
return this.http
.post(this.apiUrl + 'sites', { body }, options)
.map((res: Response) => res.json());
}
You need to add the EnableCors attribute to your SiteController class. Like this
[EnableCors(origins: "http://<SOME_SITE>", headers: "*", methods: "*")]
public class SiteController {
.....
}
refer to this link
Cannot tell from you code snippet this is the case, bit you do need it.

Angular2 http get request with Observables and dynamic url params. How to?

Having this angular2 service taken from official docs with Observable, trying to modify to can pass on fly to the base heroesUrl dynamic parameters like app/heroes/{{country}} and use it like
getHeroes(country) {}
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Hero } from './hero';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class HeroService {
constructor (private http: Http) {}
private heroesUrl = 'app/heroes'; // URL to web API
getHeroes (): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
How would I do that?
I think you just need to do following things if I understood your point,
getHeroes(country) {}
export class HeroService {
constructor (private http: Http) {}
private heroesUrl = 'app/heroes'; // URL to web API
getHeroes (country): Observable<Hero[]> { //<-----added parameter
return this.http.get(this.heroesUrl + '/' + country) //<-----changed
.map(this.extractData)
.catch(this.handleError);
}
...
...
}

Resources