AspNetCoreRateLimit
AspNetCoreRateLimit copied to clipboard
[Question]: ClientId from POST request instead of header
I need to use ClientId provided as parametr in controller's method as POST data. Is there any way?
public async Task<IActionResult> GetData([FromBody] SearchModel model)
{
var clientId = model.ClientId;
// use this clientId for throtling
}
shouldn't this work for you? https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/ClientRateLimitMiddleware#update-rate-limits-at-runtime
@RaptorCZ Hello, I also want to get the client id from raw data, do you know how to do it?
I had no idea how to do it so I made this "workaround".
I have controller with action:
public async Task<IActionResult> GetAllByRegistrationPlate([FromBody] SearchByRegistrationPlateModel model)
{
}
There is input model SearchByRegistrationPlateModel
with CustomerCode
public class SearchByRegistrationPlateModel
{
public string CustomerCode { get; set; }
}
Then I implemented custom IClientResolveContributor
and trying to find CustomerCode
in request
public class CustomResolveContributor : IClientResolveContributor
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomResolveContributor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string ResolveClient()
{
if (_httpContextAccessor?.HttpContext == null)
{
return string.Empty;
}
var request = _httpContextAccessor.HttpContext.Request;
string clientId;
try
{
request.EnableBuffering();
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
request.Body.ReadAsync(buffer, 0, buffer.Length);
var content = Encoding.UTF8.GetString(buffer);
clientId = ExtractClientIdFromContent(content);
}
catch
{
clientId = string.Empty;
}
finally
{
request.Body.Position = 0;
}
return clientId;
}
private static string ExtractClientIdFromContent(string content)
{
if (string.IsNullOrEmpty(content))
{
return string.Empty;
}
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var model = JsonSerializer.Deserialize<SearchByRegistrationPlateModel>(content, options);
var clientId = model?.CustomerCode.ToLower();
return clientId;
}
}
So it is not universal, but it works in my case.
@RaptorCZ So cool. I think this is the standard method. Thank you very much!