ASP.NET Core Kestrel throughput - c#

I create an empty asp.net core project base on .net6 and do load testing using python locust. The average response time is about 900ms, but using MiniProfile monitors the API executed time, almost zero. That's why? How to optimize it?
Load test result:
Use MiniProfile to monitor the APIs execution time:
Resource usage:
Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddMemoryCache();
builder.Services.AddMiniProfiler(opt =>
{
opt.RouteBasePath = "/profiler";
});
var app = builder.Build();
app.UseMiniProfiler();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
HomeController.cs:
using Microsoft.AspNetCore.Mvc;
namespace del.Controllers;
[Route("[controller]")]
public class HomeController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok();
[HttpPost]
public IActionResult Post() => Ok();
}
Python script:
from locust import HttpUser, task
class Date(HttpUser):
#task
def get_date(self):
self.client.get('/home')

locust has some performance problems

Related

How to resolve the error of The call is ambiguous between the following methods or properties in asp dotnet 7

I am trying to use SoapCore package in my application written in dotnet 7 and when I call the following method
app.UseSoapEndpoint<IOfferService>("/myservice.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
I get the following error
The call is ambiguous between the following methods or properties: 'SoapEndpointExtensions.UseSoapEndpoint<T>(IApplicationBuilder, string, SoapEncoderOptions, SoapSerializer, bool, ISoapModelBounder, WsdlFileOptions, bool, bool)' and 'SoapEndpointExtensions.UseSoapEndpoint<T>(IEndpointRouteBuilder, string, SoapEncoderOptions, SoapSerializer, bool, ISoapModelBounder, WsdlFileOptions, bool, bool)'
How can I resolve this?
The above snippet is part of the Program.cs and here is the Program.cs code below
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using SoapCore;
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSoapCore();
var app = builder.Build();
//app.UseSoapEndpoint<IOfferService>("/myservice.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
...the rest of the code here
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
}
app.UseSwagger();
app.UseSwaggerUI();
//app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}

UseExceptionHandler ASP.NET Core Web API

I'm trying to use app.UseExceptionHandler("/error") so I can handle all the errors using the ProblemDetails.
However, I never get rerouted to the ErrorController. When I set a breakpoint, the debugger never gets inside this endpoint.
Does anyone know why I'm not hitting my breakpoint?
The code in the program.cs is :
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
{
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services
.AddApplication()
.AddAInfrastructure(builder.Configuration);
}
WebApplication app = builder.Build();
{
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(q => q.SwaggerEndpoint("/swagger/v1/swagger.json","PowerPlanner v1"));
}
app.UseExceptionHandler("/error"); // <===============
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
}
app.Run();
Controller:
using Microsoft.AspNetCore.Mvc;
[ApiController]
public class ErrorsController : ControllerBase
{
[HttpGet("/error")]
public IActionResult Error()
{
return Problem();
}
}
Solution:
Because I Used Swagger, I couldn't declare the route with the attribute [Route("/error"]) without getting an error. To solve this, the entire controller has to be marked with :
[ApiExplorerSettings(IgnoreApi = true)]
like this:
[ApiExplorerSettings(IgnoreApi = true)] //<====
public class ErrorController : ControllerBase
{
[Route("/error")] //<=== this can only be 'route' when the controller is marked with ignoreApi=false
public IActionResult ErrorPost()
{
return Problem(;
}
}
Documentation : https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-7.0

Getting error for Swagger UI with an ASP.NET Core 6 Web API with custom routing

I have custom routing for my ASP.NET Core 6 Web API:
[ApiController]
[Route("ForecastService")]
public class WeatherForecastController : ControllerBase
{
[HttpGet("forecast")]
public IEnumerable<string> Get1()
{
return new[] { "forecast" };
}
}
I have made this change in the Swagger configuration:
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
//app.UseSwagger();
//app.UseSwaggerUI();
app.UseSwagger(c => c.RouteTemplate = "ForecastService/{documentName}/swagger.json");
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("ForecastService/v1/swagger.json", "Forcast API");
c.RoutePrefix = "ForecastService/swagger";
});
}
Now while trying to run browse to http://localhost:5113/ForecastService/swagger/index.html, I am getting an error:
Not found http://localhost:5113/ForecastService/swagger/ForecastService/v1/swagger.json
What am I missing here?
Change your configuration for swagger like below:
//miss the swagger after ForecastService.....
app.UseSwagger(c => c.RouteTemplate = "ForecastService/swagger/{documentName}/swagger.json");
app.UseSwaggerUI(c =>
{
//miss the `/` in the beginning and also miss the swagger after ForecastService...
c.SwaggerEndpoint("/ForecastService/swagger/v1/swagger.json", "Forcast API");
c.RoutePrefix = "ForecastService/swagger";
});
modify below lines as
app.UseSwagger();
app.UseSwaggerUI();
Use URL as
http://localhost:5113/swagger

.NET Core Endpoint + Global CORS

I've found this in official documentation -
We recommend against combining policies. Use the [EnableCors]
attribute or middleware, not both in the same app.
My scenario is quite simple - I want to enable CORS globally but disable it only for one specific controller endpoint (endpoint is used on frontend widget which can be embedded on any site so I can't have CORS on that endpoint).
I don't understand why they are recommending against combining both approaches - not only that they don't recommend but it just doesn't work.
This is the setup of CORS:
services.AddCors(opts =>
{
opts.AddPolicy(nameof(MyCorsPolicy), new MyCorsPolicy());
});
And this is registration in Configure method of startup
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors(nameof(MyCorsPolicy));
app.UseHsts();
app.UseExceptionHandler(env);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
And now in my XY controller method I have [DisableCors] attribute which just doesn't work.
Any help would be appreciated. Thank you.
After hundreds of tests and internal .NET Core debugging, only way I could implement this is by using global CORS:
services.AddCors(opts =>
{
opts.AddPolicy(nameof(MyCorsPolicy), new MyCorsPolicy());
});
Then I'd create another policy
public class AllowAnyCorsPolicy : CorsPolicy
{
public AllowAnyCorsPolicy()
{
Origins.Clear();
IsOriginAllowed = origin => true;
Headers.Clear();
Headers.Add("*");
Methods.Clear();
Methods.Add("*");
SupportsCredentials = true;
}
}
And apply that policy to specific controller method e.g.
[EnableCors(nameof(AllowAnyCorsPolicy))]
[HttpPost("/user/add")]
[AllowAnonymous]
public async Task<IActionResult> AddUser(UserRequestModel requestModel)
{
// ...
}
If I used [DisableCors] or even used default policy registration and then added pure [EnableCors] attribute to controller method, it just wouldn't work. Pretty weird way of their implementation because I think this can be simplified a lot, and I have no idea how this might behave in future, so we might even consider writing our own full CORS middleware.
Way 1. Because a default policy hasn't been configured, app.UseCors() alone doesn't enable CORS. Use RequireCors to enable all controllers.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers()
.RequireCors(MyCorsPolicy);//Enable Cors with endpoint routing
// /xy/getvalues2 and Razor Pages not allow cross-origin requests because no default policy was specified.
endpoints.MapGet("/xy/getvalues2",
context => context.Response.WriteAsync("xy/getvalues2")); //do XY Controller Action logic
endpoints.MapRazorPages();
});
}
Way 2. The [DisableCors] attribute does not disable CORS that has been enabled by endpoint routing. Uses [EnableCors("MyCorsPolicy")] to enable the "MyCorsPolicy" CORS policy for each controller. Disables CORS for the GetValues2 method.
[EnableCors("MyCorsPolicy")]
[Route("api/[controller]")]
[ApiController]
public class XYController : ControllerBase
{
// GET api/values
[HttpGet]
public IActionResult Get() =>
ControllerContext.MyDisplayRouteInfo();
// GET: api/values/GetValues2
[DisableCors]
[HttpGet("{action}")]
public IActionResult GetValues2() =>
ControllerContext.MyDisplayRouteInfo();
}

ASP.NET core Cors policy

I'm having problem setting up Cors policy in my ASP.NET core project.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAll",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMemoryCache();
}
I've tried adding app.UseCors("AllowAll"); in Configure(IApplicationBuilder app, IHostingEnvironment env), tried [EnableCors("AllowAll")]before controller declaration:
[Route("api/[controller]")]
[ApiController]
[EnableCors("AllowAll")]
public class TestController : ControllerBase
and before method declaration:
[HttpPost]
[EnableCors("AllowAll")]
public JsonResult Post([FromBody] dynamic request)
and no luck, I'm keep getting "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at..."
Maybe someone can help me?
I know this is too late, but can help someone,
using CorsMiddleware in specified order is matters
app.UseRouting();
app.UseCors("AllowAll");
app.UseAuthorization();
app.UseResponseCaching();
The call to UseCors must be placed after UseRouting, but before
UseAuthorization.
When using Response Caching Middleware, call
UseCors before UseResponseCaching

Categories

Resources