Swagger Response Attributes for Controller Action Errors - swagger-ui

I am struggling to find some examples of the SwaggerResponse attribute using the controller action errors in my C# web api, such as NotFound() etc.
I have this attribute on my controller method:
[SwaggerResponse(404, "Requested application not found", Type = typeof(NotFoundResult))]
And in the controller method I have this:
NotFound("No configuration found")
But in the UI I get this:
I was hoping it would at least show the code in the json and not 0?
The only thing that looks reasonable in the UI is the 200 response, which is a List<settings> which shows the list, but doesn't show examples.

After finally getting the search terms correct for this I found an answer on here that actually suppresses the error models all together, which is better than having the above in your documentation.
Using net5.0 this worked for me:
// add controllers with swagger
services.AddControllers(x => x.Conventions.Add(new ApiExplorerVersionConvention()))
.ConfigureApiBehaviorOptions(x => { x.SuppressMapClientErrors = true; });
For more info for older .Net versions see here:
Hide Swagger Bad Response for .net 2.2

Related

How to properly save updates to domain objects in Groovy/Grails

I'm starting to touch the Groovy/Grails backend of my organization and am tasked with updating the User on our Document domain object. The problem is, after hitting the update endpoint from the frontend with the correct params attached, the backend responds with an unchanged Document object.
Here is the code:
if (requestParams.userEmail) {
def contact = User.findByEmail(requestParams.userEmail)
log.debug('Reading user found by passed email contact={} error={}',contact, contact.errors.allErrors.inspect())
if (!contact) {
response.status = 400
render WebserviceError.badInput as JSON
return
}
document.user = contact
document.user.save(flush: true)
}
document.save(flush: true)
render survey as JSON
The frontend returns a promise and I'm logging the promise response, and it shows an unchanged Document object with the same exact user attached. I don't receive a 400 so it looks like the contact is successfully found.
I tried adding flush:true to the user.save call and the document.save call and that did not help.
Are there any obvious wrongdoings in my code?
Well db operations should be in a service, not in a controller, using #Transactional, preferably the gorm version not the spring version. You shouldn't need to use flush: true. Then fron the service you can return to the controller, andrender as JSON.
You don’t state that you see the debug statement on the server indicating a found user, perhaps it’s never actually getting to this section?
I assume that the code provided is incomplete, as we don’t see that the survey being returned contains the document that’s being updated. And also the braces look unbalanced, as if there’s a control flow issue. (i.e. why are there 2 opening braces but 3 closing braces?)
I’d suggest that you use a debugger on your code to see how control is actually flowing. Most Java IDEs support easy debugging, essentially clicking the debug button rather than the run button. Set a number of breakpoints sprinkled through this code to catch requests and call the API endpoint from your frontend.
is Document the parent? User a child?
User.addTodocument(someUser)
then Document.merge()

Pagination in Angular2 (On Rails5)

Normally with Rails, I'd use will_paginate and call it a day, but I'm using Rails5 purely as an API, and front-end is completely Angular2.
I've looked into NG Bootstrap4's Pagination but I'm having quite a few issues getting it to do anything besides render - And I can imagine why. What is the proper process for Paginating on Angular? I tried using will-paging to paginate the JSON but instead I just limit the results.
I also looked into ng2-pagination which seemed to have a lot of the features I wanted, but I started getting
Uncaught TypeError: ctorParameters.map is not a function errors for everything so I thought maybe I should take it a step back.
Would the proper process be to use the controller in Rails to append a 'page' parameter to the JSON Results? Or would something more like Virtualization be the route I should go?
Having quite a few issues - Even once I have the bar active, it obviously can't control my script.
getDecks(): Observable<Deck[]> {
return this.http.get(this.decksUrl)
.map((response: Response) => <Deck[]>response.json())
.catch(this.handleError);
}
this is the call that contacts the API and gets the response - I feel like I would involve the 'page' here to actually allow Pagination to do something?
I was able to figure it out - multiple issues. For those wondering:
Uncaught TypeError: ctorParameters.map is not a function seems to be a compilation issue with newer packages.
Different library but similar issues
I upgraded Ang2 + Respective libraries to remove error. From there the instructions made a lot more sense.
The pipe should be built directly into your ngFor
<span *ngFor="let deck of decks| paginate: { itemsPerPage: 10, currentPage: p }" class="list-group-item list-group-item-action">
Then placing
<pagination-controls (pageChange)="p = $event"></pagination-controls>
Where-ever you want an async bar resolves the issue.
Works perfectly - Library is Ng2-Pagination

Benefits of Post-Redirect-Get

When I started with ZF2 the first module I used was ZfcUser. When I debug it's controller's code I found a weird way (at least for me) to manage actions. I found code like
$prg = $this->prg('zfcuser/changepassword');
if ($prg instanceof Response) {
return $prg;
} elseif ($prg === false) {
return array(
'status' => $status,
'changePasswordForm' => $form,
);
}
//VALIDATE FORM AND DATABASE STUFF
(...)
The behaviour is as follows:
The first load $prg is false, so it returns the form.
When you submit the page, $prg is an instance of Response, so it returns $prg.
When $prg is returned, the same function is called again and $prg becomes an array with all the posted data, so it jumps to the validation of form and database stuff.
I thought it was a weird approach so I override all the needed functions replacing this with the simple request->isPost(). I found it easier to handle the first load/data posted.
I didn't give it more importance until now. I'm facing the Post-Redirect-Get approach again when I'm trying to upload files: it seems that is needed to prevent user to re-select the file and re-upload when a validation error rises on a form.
What's the point of the Post-Redirect-Get? When do you recommend the use of it (apart of the commented file upload)?
As the documentation states:
When a user sends a POST request (e.g. after submitting a form), their browser will try to protect them from sending the POST again, breaking the back button, causing browser warnings and pop-ups, and sometimes reposting the form. Instead, when receiving a POST, we should store the data in a session container and redirect the user to a GET request.
So the purpose of this plugin is to improve user experience. You must have came across this problem when you submit a form and try to refresh the page you get a pop-up message like (example from google chrome):
Confirm Form Resubmission: The page that you're looking for used information that you entered. Returning to that page might cause any action you took to be repeated. Do you want to continue?
You can get more details in the docs for Post/Redirect/Get Plugin, or File Post/Redirect/Get Plugin if your form handles files uploads.
NOTE: For the File Post/Redirect/Get Plugin - Example Usage there's a typo on line 16, you should use $this->filePrg() instead of $this->prg(). It should be like the line below.
$prg = $this->filePrg($myForm, '/user/profile-pic', true);

Securing gsp files

I'm relatively new to Spring, but very new to Spring Security and Grails. To be brief, I know its recommended to not allow .jsp files to be servable, you should toss them in WEB-INF, and set up your controllers to pull them from the right place.
How would I go about doing this in Grails? It seems that I would destroy the idea of "convention over configuration" by tossing gsp's into WEB-INF and then writing logic into all my controllers (if that's even immediately possible...) It seems I would have to alter some basic Grails configurations.
Any ideas?
OK, I haven't seen a complete answer for this here (or elsewhere one StackOverflow) that provides a full valid result, so here's what I've come up with:
First, create a new controller:
grails create-controller gspForbidden
Open this up, and add this to the index action:
index = {
response.status = 404
}
Then, open grails-app/conf/UrlMappings.groovy and add this under the static mappings closure:
"/grails-app/**.gsp"(controller:"gspForbidden")
This will redirect any attempts to view a GSP directly to the gspForbidden controller. That controller, in turn, simply renders a 404 - a file not found response. The best thing about this is that it's completely hidden - there's nothing showing that the GS path was correct, so there's less chance of exposing something important about the application design.
I tried repeatedly to figure out how to use UrlMappings to show a 404 without the controller, but I had no success. If you can think of a way, please let me know. I'd much rather have this happen without any explicit controllers.
Slight correction to earlier post:
Just adhering to the convention in Grails doesn't prevent someone who guesses where a gsp lives from hitting it directly (I just tried it, it works).
From Spring Security Plugin Documentation:
package com.testapp
import grails.plugins.springsecurity.Secured
class SecureController {
#Secured(['ROLE_ADMIN'])
def index = {
render 'Secure access only'
}
}
you can secure your GSP pages as the example above. Secured annotation will provide access only to a user if they have the admin rights.
for more information , refer to :
http://grails-plugins.github.com/grails-spring-security-core/docs/manual/
tutorials are nice as a start.
You actually don't need to worry about this in Grails. If you follow the conventions of using views and controllers it will handle all the details about making sure the GSP pages aren't directly accessible.
As far as integration with Spring Security is concerned, again if you follow one of the recommended patterns (URL security or annotation within your controllers) you should be fine.

Steve Sanderson's "Partial Request"

I have followed the blog post written by Steve Sanderson at blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc. It all work fine when follow it exactly but I was hoping that someone may have looked at it and be able to assist me in adapting it slightly.
I basically have this "partial request" calling from one controller to another and this works fine. I then want to foreach through the data and create a drop down list. The problem is that I need to convert it to an IEnumerable to do this but it fails telling me that I cannot convert a void to an IEnumerable.
The lkine fails on is in the view and is:
foreach (var category in (IEnumerable<MyObject>) ((PartialRequest)ViewData["ReturnedData"]).Invoke(ViewContext))
Clearly, knowing how to answer this is hard without seeing the code. This is all in the aforementioned post but as it is reasonably lengthy I do not want to post it all in here. I understand that this makes answering this difficult and am hoping that someone has ready that post and can assist.
Thanks in advance.
The PartialRequest Invoke method doesn't return anything, it writes the HTML that the request generates to the response. The idea is that you can invoke a controller action that renders an MVC View User Control rather than a View. You can make a partial request to this controller action and have it render the control directly into the response stream rather than using the Html.RenderPartial. Since the control writes directly to the response, you don't have a chance to interact with it's output.

Resources