Angular post to ASP.NET Core 6 gets 400 while Postman works fine - asp.net-core-6.0

Originally I tried to send the argument as an object, but in ASP.NET Core 6, it is failing (400 error). From the many answers, I decided to stringify the object to a string and pass it like this:
var dtoAsJson: string = JSON.stringify(this.projectCreateInitDto);
this.http.post<ProjectDto>(baseUrl + 'Projects/CreateProject/', dtoAsJson).subscribe({
next: (response: ProjectDto) => {
Stopping on the http.post, dtoAsJson was a text string of course.
The controller looks like this:
[Route("CreateProject")]
[HttpPost("{Jsondto}")]
public async Task<ActionResult<ProjectAPIDto>> CreateProject(string Jsondto)
{
ProjectAPICreateInitDto dto = Json.Decode<ProjectAPICreateInitDto>(Jsondto);
Project project = _mapper.Map<Project>(dto);
}
I stop on the Json.Decode and Jsondto is null.
I've searched for solutions, but I'm stuck.
Thoughts? Thanks in advance

The problem is that you are sending the dtoAsJson-object as the body of the POST request, but in the backend you are trying to receive it as a route parameter.
You could try the following:
[Route("CreateProject")]
[HttpPost]
public async Task<ActionResult<ProjectAPIDto>> CreateProject([FromBody] string Jsondto)
{
ProjectAPICreateInitDto dto = Json.Decode<ProjectAPICreateInitDto>(Jsondto);
Project project = _mapper.Map<Project>(dto);
}
Hint how to further improve your code:
I suppose your code will work without JSON.stringify(), if you use [Route("CreateProject")] and [FromBody] in the backend.

Related

Accessing response headers using NodeJS

I'm having a problem right now which I can't seem to find a solution to.
I'm using Uservoice's NodeJS framework to send some requests to UserVoice regarding Feedback posts. A problem I've run into are ratelimits so I want to save the header values X-Rate-Limit-Remaining, X-Rate-Limit-Limit and X-Rate-Limit-Reset locally. I've made a function for updating and getting that value and am calling it like this:
var content = "Test"
c.post(`forums/${config.uservoice.forumId}/suggestions/${id}/comments.json`, {
comment: {
text: content
}
}).then(data => {
rl.updateRL(data.headers['X-Rate-Limit-Limit'],data.headers['X-Rate-Limit-Remaining'],data.headers['X-Rate-Limit-Reset'])
When running this code I get the error Cannot read property 'X-Rate-Limit-Limit' of undefined.
This is not a duplicate, I've also tried it lowercase as described here but had no luck either. Thanks for helping out!
EDIT:
The function takes the following parameters:
module.exports = {
updateRL: (lim, rem, res) {SAVING STUFF HERE}
}
It is defined in the file rates.jsand is imported in the above file as const rl = require('../rates').

Servicestack Display 404 page CatchAllHandlers

Im using servicestack Core with kestrel. I made a CatchAllHandlers delegate with the following code.
var requestType = typeof(NotFoundPage);
var restPath = new RestPath(requestType, pathInfo);
return new RestHandler { RestPath = restPath, RequestName = restPath.RequestType.GetOperationName(), ResponseContentType = contentType };
But the problem is that my ServicestackApi now is no longer reachable, url: /json/reply/GetApiCall goes to the 404 not found page.
Is there a way to solve this? can i check if its an api call or can i go later in the pipeline to handle the request?
update
I found that if i remove CatchAllHandler and just add the next middleware this middleware is called:
app.Use((context, next) =>
{
context.Response.Body.Write("yaayaya");
return Task.CompletedTask;
});
But this is not what i want, i want to stay inside the servicestack request.
update 2
Looking at the source-code i find HttpHandlerFactory has a property NotFoundHttpHandler Which is filled from the AppHost.
CustomErrorHttpHandlers.Add(HttpStatusCode.NotFound, new PageNotFoundHandler());
The only downside is that i can't provide any request specific information to this Urlhandler, such as the url itself:
public class PageNotFoundHandler : RestHandler
{
public PageNotFoundHandler()
{
var restPath = new RestPath(typeof(Error404), "/Url/For?");
}
}
Trying to make this work but i'm getting stuck on that my RestHandler has different amount of components than the url since this PageNotFoundHandler is made before the RestHandler.
But Basically what im looking for is to Handle a different service/InputDto
I've tried RequestConverters but this code is not reached when CatchAllHandlers doesn't return an Handler. so im stuck in this space in the middle. Anyway i could make all the left over routes, route to a single Dto?
.NET Core's new pipeline programming model expects you to call the next middleware if it wasn't already handled by any of the previously registered middleware which is how .NET Core lets you combine multiple different middlewares into the same App.
Handling Not Found Requests with the last Middleware
The last middleware that's registered will be able to handle any unhandled requests so for instance if you wanted to return a static image for unhandled requests you could register middleware after ServiceStack, e.g:
app.UseServiceStack(new AppHost());
app.Use(new StaticFileHandler("wwwroot/img/404.png"));
Or if you wanted to return a custom 404 page instead:
app.Use(new RazorHandler("/404"));
Which will render the /wwwroot/404.cshtml Razor View with ServiceStack's MVC Razor Views.
This would be the preferred way to handle Not Found requests in .NET Core in which you will be able to register additional middleware after ServiceStack to handle non-ServiceStack requests.
Calling a ServiceStack Service for unhandled requests
If you wanted to call a ServiceStack Service for any unhandled requests you can use a Fallback Route which matches on any request, e.g:
[FallbackRoute("/{Path*}")]
public class Error404
{
public string Path { get; set; }
}
public class UnhandledRequestService : Service
{
public object Any(Error404 request) => ...;
}

ServiceStack NativeTypesFeature AddResponseStatus

I'm writing a backend using ServiceStack. our main front end client is an Angular 2 application using TypeScript. To that end, we are using the DTOs that are generated by the services when hitting /types/typescript and /types/typescript.d. This all works fine and good using the JsonServiceClient... but it seems that the response status code is somehow wrapped up in the call and not returned as it as when using a standard XHR call.
Finding the AddResponseStatus configuration item, I changed the service configuration to add this on any DTO that didn't already have the property (which mine didn't):
var ntf = new NativeTypesFeature();
ntf.MetadataTypesConfig.AddResponseStatus = true;
Plugins.Add(ntf);
After refreshing the TypeScript reference, I can see that all DTO types returned now have a ResponseStatus property on them.
export class QueryReportResponse
{
Data: string;
ResponseStatus: string;
}
Here is a scrubbed return (removed the 'Data' portion) showing the property exists on the object:
<QueryReportResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/blah.blah.ServiceModel.Messages">
<Data>
blah blah data here
</Data>
<ResponseStatus i:nil="true"/>
</QueryReportResponse>
Now, I assumed (wrongly so) that by doing this, some sort of status would be set 'automatically'. I'm obviously not right here, as this property is not set. My front end guy is asking to be able to see the status on all returned calls, like he was able to before when using straight XHR prior to using the JsonServiceClient, as now he cannot see the return status.
What is the intent of this field? I cannot set it manually, as it's added by ServiceStack dynamically at runtime. I can only assume that I would have to create my own base class return DTO of sorts and set that on the way back to the caller... can someone help me understand the purpose of this field? Thanks.
ServiceStack's Add TypeScript Reference is typically used with the TypeScript servicestack-client. The ResponseStatus is used in ServiceStack's Error Handling which is used to capture structured Error Information. It's not populated for successful responses and it's distinct from the HTTP Response Status code although if throwing a HTTP Error the ResponseStatus.ErrorCode will typically contain the HttpStatusCode enum string.
Adding ResponseStatus on DTOs
Adding the ResponseStatus on DTOs, e.g:
ntf.MetadataTypesConfig.AddResponseStatus = true;
Just adds the ResponseStatus on generated DTOs where they didn't previously exist. It doesn't have any effect on Response DTOs which already includes the ResponseStatus property, e.g:
public class MyResponse
{
public ResponseStatus ResponseStatus { get; set; }
}
Accessing HTTP Status Responses
Developers shouldn't care what the HTTP Status code is for successful responses (which is almost always 200 OK). ServiceStack's TypeScript JsonServiceClient will just return the Typed Response DTO for successful responses, e.g:
var response = await client.post(request)
They should only be interested for handling error responses, however it's expected to use the ResponseStatus.ErrorCode to determine the type of Error and apply application error handling logic, e.g:
try {
var response = await client.post(request)
} catch (e) {
console.log(e.responseStatus.errorCode);
}
If they really want the HTTP Status they can get it using a response filter, e.g:
var status = null;
try {
client.responseFilter = res => status = res.status;
var response = await client.post(request)
} catch (e) {
console.log(status, e.responseStatus.errorCode);
}

Play Framework 2.x always send single response code

Hopefully you guys can help me with this! I have a problem where I need to send a constant response code no matter what the request contains. If the request has bad JSON etc. The response I need to send is a 204 (No Content)
Here's my code where I try to send back a no content header.
public Result response(){
RequestBody body = request().body();
System.out.println(body.asJson());
return noContent();
}
Now if I try and send a request containing JSON like below. It returns a 400 (Bad request). I want to send a 204 no matter what. Please let me know what you guys come up with.
JSON POST
{
"mike":"mike
}
Thanks
Edit:
Sorry I replaced one of these lines of code and forgot to update this. Above I only return 204's, but if my client sends me bad JSON then I still return a 400.
You need to modify the global settings for play.
Create a class that extends Global Settings and override whichever method you want.
public class Global extends GlobalSettings {
#Override
public Promise<Result> onBadRequest(RequestHeader arg0, String arg1) {
super.onBadRequest(arg0, arg1);
return F.Promise.promise(()->{return play.mvc.Results.noContent();});
}
}
For more information : https://www.playframework.com/documentation/2.4.x/JavaGlobal
To return 204, you can use noContent method
For that replace ok() by noContent()
Try this,
#BodyParser.Of(BodyParser.Json.class)
public static Result response() {
JsonNode json = request().body().asJson();
if(json == null){
return noContent();
}else{
// Get json content from request and process rest..
}
return ok("");
}
By using above approach, a 204 HTTP response will be automatically returned for non JSON requests.

How do I pass parameters through "use" method in CompoundJS?

I am using CompoundJS (an MVC for Express / NodeJS). To share code between controllers the Doc says that on controller1.js I can share a method by using publish method:
/***controller1.js***/
function sharedFunction () {...}
publish('sharedFunction', sharedFunction); //Sharing...
And in the controller2.js I can access it by loading it and trying the use method:
/***controller2.js***/
load('controller1'); // _controller siffix must be omitted
use('sharedFunction')
PROBLEM
This works great, however, I have a sharedFunctionthat has params:
/***controller1.js***/
function sharedFunction (param1, param2) {...}
publish('sharedFunction', sharedFunction); //Sharing...
I have been reading the Docs, however I can't find how, or the syntax, to add this params on my usemethod on controller1.js. Where do I send these params?:
/***controller2.js***/
load('controller1'); // _controller siffix must be omitted
use('sharedFunction(params here?)', {params here?}) //where do I send the params?
Thank you very much!
Here's what I've done:
var sharedFunction = use('sharedFunction');
sharedFunction(param1, param2);

Resources