I have Swagger setup for an ASP.NET Core 2 MVC API application. I'm using OpenIddict for OAuth but want to customize how the request and responses appear on the documentation.
Since the method in the controller takes an OpenIdConnectRequest, the generated default output looks like so:
... and it just goes on and on.
This is a far cry from the neat JSON required for a client to consume since the middleware does a bunch of work inbetween the client and the controller method.
How do I change how Swagger represents these? I am already using a hack to massage the responses via a custom, private type for token responses, so any help on how to use that would also be appreciated. I have tried to use the SwaggerGenOptions.MapType<> function as the documentation claims that tells Swagger how to map a type to a custom output. Unfortunately, I've not gotten the Swagger output to reflect anything I've done with .MapType<>.
To be clear, these aren't models I control so I can't decorate the members myself.
Note that this is different from How to show WebApi OAuth token endpoint in Swagger. My controller action is discovered fine. Unfortunately, I'm thinking it may be easier to filter it out and use that as another work around to define it manually but I'd rather not if possible.
Related
Given a URL, and I want to know which action in which controller is responsible for handling that URL. What I do right now is that I search for the route name in the project from visual studio. But I think there might be a package or tool that lists the routes and their corresponding Controller actions.
Is there a more neat way to find that:
url/examples/1
is handled by:
[HttpGet]
[Route("examples/{id}")]
public Task viewExmaple()
Try Swagger, as I think this will be as close as you can get in terms of "lists the routes and their corresponding Controller actions". By default, swagger acts a GUI (web page) that displays every controller with corresponding controller methods nested beneath(accordion style).
Swagger is also a great tool for debugging and testing. It displays details like which HTTP verb the methods use, which query string params (or JSON payload in body) the method accepts. Great for documentation as well.
Behind the scenes, swagger builds one giant JSON payload that nests all of your controller / controller actions so you may also be able to view it like that.
You would access it by hitting http(s)://your.app.path/swagger
Setting up in a .NET Standard (Non-Core) app
I am currently trying to use Swagger UI to interact with my OData enabled Web API.
Versions for the bits and bobs are as follows:
.Net 4.5.2,
Web API 2.2,
NuGet package Microsoft.AspNet.OData 6.0.0 for OData 4.0 endpoints,
Swashbuckle 5.3.2,
Swashbuckle.Core 5.3.2,
Swashbuckle.OData 3.0.0.
My application has a SwaggerConfig.cs and a WebApiConfig.cs as expected. And I have followed many of the instructions in this article, this article and a few others on the web.
When I launch my API through Visual Studio, I initially get a new browser tab with the local host URL. If I append the word "/swagger" (no quotes) at the end of that URL, I get a nice Swagger UI in the same tab. This tab shows the name of of my API but not much else. I don't see any of the individual URL interfaces for the Actions exposed by my ODataController derived Controller. Moreover, underneath the displayed name of the URL, all I have is [ base url: , api version: v1 ] where "v1" is coming in from SwaggerConfig.cs (same with the API name).
I know I can talk to the API from Swagger UI because I can arrive at the "Get" action of the Controller by modifying the displayed URL appropriately. The actions created were the standard Get, Put, Post, Patch, Delete ones. But I cannot see any of these in the Swagger UI.
This is because I am new to this and obviously have missed out or miscoded stuff to link everything correctly. I have made very little change to SwaggerConfig.cs and left most of the things as they were when it was created. The significant change I have made was adding this line:
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration));
Based on this info, if anyone can guide me in the direction of what pieces could be missing or developed incorrectly, I would greatly appreciate it. If you had any further questions for me, I would be happy to respond in the comments.
It turns out that because I had been recreating the application, Entity Framework was no longer creating the database for me since it was trying to use a name it had already recently used (a known EF bug). So I refractored the name of the database to something else. After this, things were plain sailing.
This negates my comment: "I know I can talk to the API from Swagger UI because I can arrive at the "Get" action of the Controller by modifying the displayed URL appropriately. The actions created were the standard Get, Put, Post, Patch, Delete ones. But I cannot see any of these in the Swagger UI."
Clearly this was me not understanding the issue clearly. But by going through the steps again one by one, I was able to find the problem and come to the desired place :)
I need to create ASP.NET WebApi with couple operation, for example RegisterAppStart, RegisterStep and RegisterAppEnd. And I want to place all this actions in one controller. As I read, usually in WebApi action name is not using.
And my question - is this a bad idea to rewrite default route config with actions using?
ps. sorry for my English
You can give actions arbitrary names using the [Route("/api/FooController/BarMethod"] attribute routing.
This usually overrides the "REST"yness of your service (where the request method indicates which method should be called), but as you aren't really building a REST service, you shouldn't care.
I am currently following this tutorial to create a simple REST service using Web Api. Note this is my first time doing something like this and I am just trying to learn more.
http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations
I have followed all the instructions and have it successfully running on my localhost. I understand that in this tutorial the URI for all my GET requests look something like:
localhostapi/products/id
And I understand that, and how to perform simple GET requests in the URI and see it actually occuring using my developer tools in my browser.
Now my question is... How do I make POST/DELETE/PUT requests and actually see what they are doing? The guide wasn't too clear, do I pass in parameters into the URI? Does the URI change when I want anything but a GET request? This text here seems to explain it but I do not understand:
The method takes a parameter of type Product. In Web API, parameters with complex types are deserialized from the request body. Therefore, we expect the client to send a serialized representation of a product object, in either XML or JSON format.
It's quite easy to make POST, PUT, DELETE requests. You just need to install Fiddler at http://www.telerik.com/download/fiddler
Next, install and run it. Go to the Composer tab on the right hand side. Next, put your local host URL, and the request method, and other data like the screenshot below
You can write unit tests, like
[TestMethod]
public void GetAllProducts_ShouldReturnAllProducts()
{
var testProducts = GetTestProducts();
var controller = new SimpleProductController(testProducts);
var result = controller.GetAllProducts() as List<Product>;
Assert.AreEqual(testProducts.Count, result.Count);
}
This link also This one may help.
more:
How to call ASP .NET MVC WebAPI 2 method properly
Sending C# object to webapi controller
You can set a breakpoint on your controller methods that handle the post/delete/put.
Same thing in your browser at the point where you call the post/delete/put (presumably in a jquery request)
You can also unit test your controller methods:
http://www.asp.net/mvc/tutorials/older-versions/unit-testing/creating-unit-tests-for-asp-net-mvc-applications-cs
I was thinking ,
The WebApi along with routing mechanism works in such way that it reads the http verb ( GET POST etc...) and then searches for matched method names / parameters :
For example :
If it's GET and the URI is api/Customers/5:
method should start with Get
if it has ID so search a method which accepts int as parameter.
etc. (there are more rules).
I mostly believe they did it using reflection.
Question :
Isn't it a performance hit , for every URI request - to search all this data just to attach a method ?
Where I could easily send a very short string from a client which will imply on the method on the server side ?
Why not doing it the simple way ? Ok cause we want to use http verbs as meaning. OK. but so much operations just to execute a method
example #1
get api/Customers/5
could be
a.ashx?m=gc&id=5 (method=GetCustomer & id=5)
example #2
put api/Customers/5?v=123
could be
a.ashx?m=uc&id=5?v=123' (method=UpdateCustomer & id=5 & value=123)
mine is even shorter.
Dont get me wrong. I believe this api was done by very smart people who knew what they talk about.
Just want o know what am I missing.
Web api has a lot of options that you don't have with HTTP Handler if you don't code it
Full list: http://www.asp.net/whitepapers/mvc4-release-notes#_Toc317096197
OData support (via Queryable attribute)
Content Negotiation
Filters
Model binding and validation
Ability to self host outside of IIS
Link generation to related resources that incorporates routing rules
Full support for routes/routing
Ability to create custom help and test pages using IApiExplorer
Performance comparison HttpHandler vs WebAPI: http://www.west-wind.com/weblog/posts/2012/Sep/04/ASPNET-Frameworks-and-Raw-Throughput-Performance
As always, you need to choose the the technology that suits you best, if you want performance go with Http Handler. If you want flexibility and rest go with Web API. You might want rest if you expose web services that other will consume