How do I add description to FromHeaderAttribute - c#

FromHeader only has a Name property and doesn't have description. How do I change the description?
public async Task<IActionResult> Test([FromHeader] string Authorization)
{
}

Updated your csproj to use xml documentation:
Update your program.cs
Then your xml comments will show, like mine:

You should include the using System.ComponentModel then add an annotation to the controller method like this:
[Description("This description will appear in docs")]
[HttpPost]
public async Task<IActionResult> Test([FromHeader] string Authorization)
{
}
Hope help you.

Related

Asp.net core 3.1 Replace Slash (/) by question Marq (?) in the Url

In an Asp.net core 3.1 we want to configure the routing.
We have a GetDepart action
[HttpGet("GetDepart/{id}")]
public async Task<ActionResult<Depart>> GetDepart(int id)
{
//Return a Department
}
How to configure routing to replace slashes (/) with question Mark (?)
In Url,
therefore instead of having http://localhost:44339/Departs/GetDepart/1, we want to have http://localhost:44339/Departs/GetDepart ?id=1
You're probably looking for Sources.
Something like this should get you where you want to be ...
[HttpGet("GetDepart")]
public async Task<ActionResult<Depart>> GetDepart([FromQuery] int id)
{
//Return a Department
}
Notice the [FromQuery] attribute on the id parameter.
HttpGetAttribute need template parameter,but template cannot contain the '?' character,it is by design.
So if you want to use ?id=1,you can use like this(but this way is different from route,When http://localhost:44339/Departs/GetDepart it can also go to the action):
[HttpGet("GetDepart")]
public async Task<ActionResult<Depart>> GetDepart(int id)
{
//Return a Department
}
You don't need to add [FromQuery] before int id,model binding will find it in query string by default.You can refer to official document of model binding.

NSwag MSBuild "The method 'get' on path '/api/Account' is registered multiple times"

I'm trying to generate a swagger specification with NSwag.MSbuild but whenever I do it throws me this message:
The method 'get' on path '/api/Account' is registered multiple times
Now the problem is that my methods are route-less as shown below with some examples of the controller
[HttpPost]
[HttpGet]
[AllowAnonymous]
public IActionResult ExternalRegister(string provider, string returnUrl = null)
[HttpGet]
public IActionResult AddLogin(string provider, string returnUrl)
[HttpGet]
[AllowAnonymous]
public ActionResult SignUpConfig()
I understand why it does this but what I don't understand is that doing the same thing in NSwag Studio works, the command I use is $(NSwagExe_Core22) webapi2swagger is there an option so that it generates successfully like NSwag Studio?
In a WebAPI if you have more than one HttpGet or HttpPost etc you should add Route Attribute to distinguish them.
Add HttpGet["{name}"]
Turns out you don't have to specify the routes if you don't want to it has something to do with the Default Url Template:
/DefaultUrlTemplate:"{controller}/{action}/{id?}"
adding {action} solved it for me
In my case, I had already added custom [Route("")] attributes to all the paths. The problem was I had two public helper methods in the controller which NSwag identified as GET methods. Simply making them private (which they should have been anyway) made the problem go away...
In my case I had
[HttpGet, ActionName("Stuff")]
public async Task<Stuff> GetStuff(long byId, string color)
{
/* Do things one way */
}
[HttpGet, ActionName("Stuff")]
public async Task<Stuff> GetStuff(string byName, string color)
{
/* Do things another way */
}
The problem was that there were two identically named routes that take in different parameters. This is an overload situation that ASP.NET seems to be perfectly fine with but apparently blows NSwag's mind.
Because this was in legacy code, renaming the methods was not an option for me so I created a single method with optional parameters like so:
[HttpGet, ActionName("Stuff")]
public async Task<Stuff> GetStuff(string color, long? byId = null, string byName = null )
{
if (byId != null)
{
/* Do things one way */
}
else
{
/* Do things another way */
}
}
What helped me in this situation was to set the Route Attribute like this:
[Route("SignUpConfig")] ,[Route("AdLogin")]
If your controller is decorated with
[Route("[controller]")]
then you need you specify separate names
HttpGet("get1") and HttpGet("get2")
Else it will pick if decoration contains action name it it like
Route("[controller]/[action]") or from default route {controller}/{action}/{id?}

WebApi 2 routing with ? or /

I just added swagger to my api to generate some documentation...
normally, my front end code would do a "get by id" like this:
https://whatever.com/api/GetDisplayContainer/A90555CD-931E-4D9D-D51D-08D63E83FCC6
however, swaggers "try it" wants to send:
https://whatever.com/api/GetDisplayContainer?id=A90555CD-931E-4D9D-D51D-08D63E83FCC6
I want to be able to support both ways. How do I do it?
Here is an example of a controller method:
[HttpGet]
[Route("GetDisplayContainer")]
public ApiResponse<ContainerDisplayViewModel> GetDisplayContainer(Guid id)
{
return ApiResponse.Convert(ResourceService, _containerService.GetDisplayContainerById(id));
}
I don't really want to have to change my existing code to do it the "query string" way. because its a totally valid way of doing it. But it would be nice to be able to support both...
This is C# using .net core 2.1.
Thanks!
You can do two routes:
[HttpGet]
[Route("GetDisplayContainer")]
public ApiResponse<ContainerDisplayViewModel> GetDisplayContainer([FromQuery] Guid id)
{
}
and
[HttpGet]
[Route("GetDisplayContainer/{id}")]
public ApiResponse<ContainerDisplayViewModel> GetDisplayContainerRoute([FromRoute] Guid id)
{
}
If you change your route from GetDisplayContainer to GetDisplayContainer/{id} then Swagger will know that the parameter is not located in the query string and should generate your desired output.
Full code:
[HttpGet]
[Route("GetDisplayContainer/{id}")]
public ApiResponse<ContainerDisplayViewModel> GetDisplayContainer(Guid id)
{
return ApiResponse.Convert(ResourceService, _containerService.GetDisplayContainerById(id));
}

Web API routing with DTO object - C#

I have two projects, one is SPA and the other one is ASP.NET aspx project.
Normally those two projects communicate with each other via web API.
There is a running method like this (from SPA to ASP.NET)
[HttpPost]
[Route("DenyInvoice/{approvalId:long}")]
public IHttpActionResult DenyInvoice(long approvalId)
{
string exMsg = "";
if (DenyInvoice(approvalId, this.UserId, this.Email, out exMsg))
return Ok();
return BadRequest(exMsg);
}
This method works as I wanted, but I want to write a method that accepts a DTO variable like;
[HttpPost]
[Route("InvoiceDetailUpdate/{invoices : invoiceDetailDtoModel}")]
public IHttpActionResult InvoiceDetailUpdate(invoices : invoiceDetailDtoModel)
{
....
}
Is it possible? How should I do this?
Can you help?
Thank you..
Use [FromBody] to pass in the POST parameter. See https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api#implement-the-other-crud-operations for more details.
[HttpPost]
[Route("InvoiceDetailUpdate")]
public IHttpActionResult InvoiceDetailUpdate([FromBody]InvoiceDetailDtoModel invoices)
{
....
}
You want to retrieve parameter via post so there is no required for get parameter routing.
[HttpPost]
[Route("InvoiceDetailUpdate")]
public IHttpActionResult InvoiceDetailUpdate(InvoiceDetailDtoModel invoices)
{
....
}
Also, be careful with the name convention of a class.
In the following code, you can use like this :
public class BooksController : ApiController
{
[Route("api/books")]
public IEnumerable<Book> GetBooks() { ... }
[Route("api/books/{id:int}")]
public Book GetBook(int id) { ... }
[Route("api/books")]
[HttpPost]
public HttpResponseMessage CreateBook(Book book) { ... }
}
Now , you can see this link attribute-routing-in-web-api-2
and change your code to above figure
[Route("api/YourController/InvoiceDetails")]
public IHttpActionResult InvoiceDetailUpdate(InvoiceDetails invoiceDetailsDto)

How to support both 'regular' and 'readable' urls in Web API attribute rouring?

I have ASP.NET Web API 2.1 project with attribute routing enabled, and a controller action decorated as following:
[Route("api/product/barcode/{barcodeType}/{barcode}")]
public async Task<IHttpActionResult> GetProduct([FromUri] BarcodeSearchCriteria searchCriteria)
where BarcodeSearchCriteria is a complex type:
public class BarcodeSearchCriteria
{
public string Barcode { get; set; }
public string BarcodeType { get; set; }
}
It works well for a 'regular' url like this:
/api/product/barcode/EAN/0747599330971
but how in the same time support an url like this:
/api/product/barcode/?barcodeType=EAN&barcode=0747599330971
I used to use it in my *.webtest before switched to 'readable` mode.
you could have 2 routes in this case:
[Route("api/product/barcode")] //expects values from query string
[Route("api/product/barcode/{barcodeType}/{barcode}")] //expects value from route
public async Task<IHttpActionResult> GetProduct([FromUri] BarcodeSearchCriteria searchCriteria)
It looks like there is no route defined for the regular Url with query string parameters.
Try making the route parameters optional like this.
[Route("api/product/barcode/{barcodeType=""}/{barcode=""}")]
public async Task<IHttpActionResult> GetProduct([FromUri] BarcodeSearchCriteria searchCriteria)
So it should also match the route template api/product/barcode route.
Haven't tested, though hope you got my point.

Categories