How can I add links to other controller methods in generated OpenAPI specs using attributes in ASP.NET Core? - asp.net-core

I am using SwaggerGen to generate an OpenAPI spec for our API, and would like to add links between certain endpoints.
OpenAPI 3.0 Links
Is there a way to add an attribute to the controller method that links to another controller method?
For example, if I currently have something like
[HttpPost]
[Route("~/users")]
[ProducesResponseType(typeof(ResponseObject<UserId>), StatusCodes.Status200OK)]
public async Task<IActionResult> CreateUser(...)
{
// Create user
}
[HttpGet]
[Route("~/users/{userId}")]
[ProducesResponseType(typeof(ResponseObject<User>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetUser(...)
{
// Get newly created user
}
Could I somehow link them like
[HttpPost]
[Route("~/users")]
[ProducesResponseType(typeof(ResponseObject<UserId>), StatusCodes.Status200OK)]
[Link(nameof(GetUser), "UserId")]
public async Task<IActionResult> CreateUser(...)
{
// Create user
}
[HttpGet]
[Route("~/users/{userId}")]
[ProducesResponseType(typeof(ResponseObject<User>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetUser(...)
{
// Get newly created user
}
to generate the "links" field as shown in the OpenAPI 3.0 spec linked above?

Related

In Asp Net Core, Do I have to put the Attribute of [Authorize] for both Get and Post Method?

In the controller, normally we have a Get and a Post methods
for example:
[HttpGet]
[Authorize(Policy = "AdminMs")]
public async Task<IActionResult> MSCreate()
{
}
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Policy = "AdminMs")]
public async Task<IActionResult> MSCreate(empolyee)
{
}
Do I have to set the Authorize Attribute for both methods or only for HttpGet?
If you need only authorized access to any of the end points, you have to use [Authorize] on whichever method that corresponds to that endpoint. Having it on one method does not mean that it will restrict the other method even if they have similar method names.

Does someting like AcceptRequestType exists in ASP.NET Core Web API?

I would like to have a single controller action to accept different types as request and I would like to have them automatically generated with Swashbuckle. There is possibility of annotating Web API method with Attribute ProducesResponseType on method of controller like this:
[HttpGet()]
[ProducesResponseType(typeof(typeName))]
public Task<IActionResult> Method()
{
//...
}
Does exists a similar option for request types? Something like this:
[HttpGet()]
[AcceptRequestType(typeof(concreteTypeName1))]
[AcceptRequestType(typeof(concreteTypeName2))]
public Task<IActionResult> Method(AbstractType model)
{
//...
}
You can use the following attribute:
[Consumes("application/json")]

Why does not working version in asp.net core controller

I want to use api version in my .net core project.Then search web and find that's solution.
Even though do exactly all solutions,but I can't get desired result.
So if any can help me,Please show me..
I add Microsoft.AspNetCore.Mvc.Versioning 4.0.0 Package in my project and ..
StartUp.cs
Then in my Controller Add Rout Attribute as Shown :
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
private readonly IBus _client;
private readonly string AppBaseUrl = MyHttpContext.AppBaseUrl;
//private readonly IGetUrl _globalUrl;
public SellerController(IBus client/*, IGetUrl globalUrl*/)
{
_client = client;
//_globalUrl = globalUrl;
}
[HttpGet("/Sellers/{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
...
}
}
With these code I expected that I can send request to 'Info' method by this url :
But that's not working and get 404 error code status.. when I delete "/v1.0" from url and send request, that's working. I will be glad to help me .. Thanks
In your code, we can find that you applied [HttpGet("/Sellers/{SellerId}")] with route
template begin with / to Info action method, which don't get combined with route templates applied to the controller. To make request to 'Info' method, you could use below URL.
https://localhost:5090/sellers/17
I expected that I can send request to 'Info' method by this url : https://localhost:5090/v1.0/sellers/17
To achieve your requirement, you can try to modify the code like below.
[HttpGet("/v{version:apiVersion}/Sellers/{SellerId}")]
public async Task<IActionResult> Info(long SellerId)
{
//...
//for testing purpose
return Ok(SellerId);
}
Test Result
Update:
If you'd like to include v{version:apiVersion} in route template of controller level attribute routing, you can try to apply [HttpGet("{SellerId}")] to Info action method and make request with https://localhost:5090/v1.0/seller/17.
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
[HttpGet("{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
//...

How do I get Route attribute to work in .net core api?

So I added a controller to a blank asp.net CORE Api.
public class IsAliveController : ControllerBase
{
[HttpPost]
[HttpGet]
[Route("isalive")]
public object Get()
{
return "I'm alive";
}
}
Then I try to access it via https://localhost:44361/isalive
and I get no response. Do I need to make some modifications to my Startup.cs?
First why have you declared your method both as a get and a post request? you can remove the post attribute.
By default your routing must start with your controller name, add this:
[Route("[controller]")]
[ApiController]
public class IsAliveController : ControllerBase
{
[HttpGet]
public object Get()
{
return "I'm alive";
}
}
Now when you call https://localhost:44361/isalive you will receive the expected response.
There are two solutions to your problem:
#1 Your controller Name is IsAlive and you have added a route attribute on your action method as isAlive, so this would work only if you call using this Url
https://localhost:44361/isalive/isalive
#2 Remove the Route attribute from the action method
public class IsAliveController : ControllerBase
{
[HttpGet]
public object Get()
{
return "I'm alive";
}
}
and you will be able to access using Url
https://localhost:44361/isalive
Found the issue. The template I choose (using Visual studio 2019) was:
Asp.net core web app > Web Application
The startup file in this template is missing a line that I needed to add:
app.UseEndpoints(endpoints =>
{
//Add this line
endpoints.MapControllers();
});
After adding that line the endpoint works without any changes to the controller.

Routing GET and POST routes in ASP.NET MVC 4

I am trying to setup a Login form in an ASP.NET MVC 4 app. Currently, I have configured my view as shown here:
RouteConfig.cs
routes.MapRoute(
"DesktopLogin",
"{controller}/account/login",
new { controller = "My", action = "Login" }
);
MyController.cs
public ActionResult Login()
{
return View("~/Views/Account/Login.cshtml");
}
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model)
{
return View("~/Views/Account/Login.cshtml");
}
When I attempt to visit /account/login in the browser, I receive an error that says:
The current request for action 'Login' on controller type 'MyController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Login() on type MyApp.Web.Controllers.MyController
System.Web.Mvc.ActionResult Login(MyApp.Web.Models.LoginModel) on type MyApp.Web.Controllers.MyController
How do I setup a basic form in ASP.NET MVC 4? I've looked at the sample Internet App template in ASP.NET MVC 4. However, I can't seem to figure out how the routing is wired up. Thank you so much for your help.
I haven't tried this yet but can you try annotating your Login actions with the appropriate Http Verb - I'm assuming that you're using a GET for viewing the login page and a POST for processing the login.
By adding [HttpGet] for the first action and [HttpPost] for the second action the theory is that ASP.Net's routing will then know which Action method to call based upon which method has been used. Your code should then look something like this:
[HttpGet] // for viewing the login page
[ViewSettings(Minify = true)]
public ActionResult Login()
{
return View("~/Views/Account/Login.cshtml");
}
[HttpPost] // For processing the login
[ViewSettings(Minify = true)]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model)
{
return View("~/Views/Account/Login.cshtml");
}
If this doesn't work, consider having two routes and two differently named actions like below:
routes.MapRoute(
"DesktopLogin",
"{controller}/account/login",
new { controller = "My", action = "Login" }
);
routes.MapRoute(
"DesktopLogin",
"{controller}/account/login/do",
new { controller = "My", action = "ProcessLogin" }
);
There are other similar questions and answers on StackOverflow already, take a look at: How to route GET and DELETE for the same url and there is also the ASP.Net documentation which might also help.