Swagger, open api with .net Core 3.0 - c#

I have a .net core 3.0 application and I am trying to implement Swashbuckle package . So I can do a http get request.
I have a controller like this:
[Route("api/products")]
[ApiController]
public class ProductValuesController : Controller
{
private DataContext context;
public ProductValuesController(DataContext data)
{
this.context = data;
}
[HttpGet("{id}")]
public Product GetProduct(long id)
{
return context.Products.Find(id);
}
public IActionResult Index()
{
return View();
}
}
and the startup.cs file looks like this:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
services.AddDbContext<DataContext>(options =>
options.UseSqlServer(connectionString));
services.AddControllersWithViews();
services.AddRazorPages();
services.AddSwaggerGen(options => {
options.SwaggerDoc("v1", new OpenApiInfo { Title = "SportsStore", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider services)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
app.UseSwagger();
app.UseSwaggerUI(options => {
options.SwaggerEndpoint("/swagger/v1/swagger.json",
"SportsStore API");
});
// SeedData.SeedDatabase(services.GetRequiredService<DataContext>());
}
}
But if I start the application and browse to:
https://localhost:5001/swagger/v1/swagger.json
I will see this error:
NotSupportedException: Ambiguous HTTP method for action - ServerApp.Controllers.ProductValuesController.Index (ServerApp). Actions require an explicit HttpMethod binding for Swagger 2.0
So my quesiton is: what I have to change, so that it will work?
Thnak you.

I had this issue as well, it looks like the IActionResult Index() is causing the issue. You can do as mentioned above and decorate it with [NonAction] attribute and then it should fix it.

Decorate your public non - REST methods in the Controller as [NoAction]

Related

API post not decting raw json model

once again, I'm trying to hit post method of controller but the method is not catching json model. rest, all types of headers are working instead of json post.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
readonly string CorsPolicy = "MyPolicy";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add Cors
services.AddCors(o => o.AddPolicy(CorsPolicy, builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(CorsPolicy);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Can anyone please guide me on what should I need to change?
or where am I wrong in this?
Try matching case of field name, and include quotes, e.g. "DepartmentId": 0
And confirm request has Content-Type: application/json
since you are using json , you have to add [FromBody] to the action
pubic ActionResult Post([FromBody] department)
also fix json in postman
{
"DepartmentId": 0,
"DepartmentName": "bpu"
}
also to support no sensitive letter case add these options to startup
using Newtonsoft.Json.Serialization;
.....
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());

ASP.NET Core weird URL parsing. Single query string parameter

I want to pass a string parameter to an action. Acreated a method in the HomeController with the following signature:
[HttpGet]
public IActionResult TestView([FromQuery] string test)
{
return View(test);
}
This is my configuration class:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
When I go to https://localhost:5001/Home/TestView it works ok
When I add a query string ?test=myvalue it fails to find the view. It tries to locate the view using weird paths.
InvalidOperationException: The view 'myvalue' was not found. The following locations were searched:
/Views/Home/myvalue.cshtml
/Views/Shared/myvalue.cshtml
Is that a bug?
The behavior is occurring because you passed the value "myvalue" as the first parameter of your returned ViewResult, which is the viewname parameter:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.viewresult.viewname?view=aspnetcore-5.0
If you change your return statement to:
return View();
Then you won't be passing a view name parameter and it will then search for a view named TestView.

MVC controller API access in Blazor not working with .NET Core 3.0

I am trying to setup a Blazor Server side app, but running into an issue with the app reading data from my MVC Controller API. I have a controller for my model Study called StudyController. I can access the json data for my GetAll() route "/studies" when I launch the Blazor app, but the Blazor app is not reading the data. Code below:
StudyController:
[Route("studies")]
[ApiController]
public class StudyController : ControllerBase
{
private StudyRepository _ourCustomerRespository;
public StudyController()
{
_ourCustomerRespository = new StudyRepository();
}
//[Route("Studies")]
[HttpGet]
public List<Study> GetAll()
{
return _ourCustomerRespository.GetStudies();
}
}
Razor page function section trying to access data:
#functions {
IList<Study> studies = new List<Study>();
protected async Task OnInitAsync()
{
HttpClient Http = new HttpClient();
studies = await Http.GetJsonAsync<List<Study>>("/studies");
}
}
Startup.cs configuration code:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => options.EnableEndpointRouting = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddControllers();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseMvcWithDefaultRoute();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
It appears the issue was that OnInitAsync() no longer works in the latest version of Blazor. I switched to using OnInitializedAsync() and that data loaded correctly.
You Can get any exception like
"An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set."

Attribute routing for simple ping controller with Get() not working

I have simple asp.net core web api with a nudge controller that returns true for Get request. The PingController.cs looks as follows:
[Route("api/[Controller]")]
public class PingController : Controller
{
[HttpGet]
public IActionResult Get()
{
return Ok(true);
}
}
Why is navigating to the controller (http://localhost:56103/api/Ping) returning 404 ?
I added route on top of the controller and the HttpMethod for specific action. What is it that I am missing or not understanding here ?
When I add app.UseMvcWithDefaultRoute() in Startup.cs the controller works fine. (This is also confusing me.)
Startup.cs looks like the following :
public class Startup
{
public IConfiguration Configuration { get; set; }
public Startup()
{
Configuration = BuildConfiguration();
}
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
...
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
ConfigureRoutes(app);
}
private static void ConfigureMvc(IServiceCollection services, Config config)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)// auto generated
.AddJsonOptions(options => { options.SerializerSettings.Formatting = Formatting.Indented; })
.AddControllersAsServices();
}
private static void ConfigureRoutes(IApplicationBuilder app)
{
//app.UseMvcWithDefaultRoute();
}
}
You need to add UseMvc() or UseMvcWithDefaultRoute() in startup to define routing.
UseMvcWithDefaultRoute adds a default route named 'default' to the request execution pipeline and equals to
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

ASP.NET Core 2.2 Returning 404 for every other Controller

I'm working on an ASP.NET Core Application and one of my Controllers works fine. But every controller after that does not seem to work, returning 404.
This controller responds as expected:
namespace App.Controllers {
[Route("api/[controller]")]
public class AccountController : CustomControllerBase {...}
}
But this controller, and all others, return 404:
namespace App.Controllers {
[Authorize]
[Route("api/[controller]")]
public class UserController : CustomControllerBase {...}
}
CustomControllerBase looks like this:
namespace App.Controllers {
[ApiController]
public class CustomControllerBase : ControllerBase {
public CustomControllerBase() {
}
}
}
And my Startup.cs looks like this:
namespace App {
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<DatabaseContext>(options => options.UseMySql(Configuration.GetConnectionString("MySQLConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<DatabaseContext>();
services.AddScoped<IUserService, UserService>();
services.Configure<JWTSettings>(Configuration.GetSection("JWT"));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
} else {
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}"
);
});
app.UseAuthentication();
}
}
}
Any ideas? I've been stuck on this for a few days and I cannot figure out what I am doing wrong.
Thanks

Categories