vizvezetek
vizvezetek

Reputation: 61

How to set "dynamically" (from appsettings.json) the request size - [RequestSizeLimit()] - on every controller function in .net core

I would like to configure the uploadable file size of the request from the appsettings.json on every controller method with different parameter, but I don't want to set it globally. How can I do it?


public long GetCatMaxFileUploadSize()
{
    return _appSettings.Value.CatSettings.GetUploadFileSize;
}

public long GetDogMaxFileUploadSize()
{
    return _appSettings.Value.DogSettings.GetUploadFileSize;
}

public long GetRabbitMaxFileUploadSize()
{
    return _appSettings.Value.RabbitSettings.GetUploadFileSize;
}

...

[HttpPost]
[RequestSizeLimit(1000000)] //1MB -> set this value "dynamically" from appsettings.json
[RequestFormLimits(MultipartBodyLengthLimit = 1000000)]
public IActionResult CatConfigUploader([FromForm] IFormFile jSonFile){
    ...
}

[HttpPost]
[RequestSizeLimit(50000000)] //50MB -> set this value "dynamically" from appsettings.json
[RequestFormLimits(MultipartBodyLengthLimit = 50000000)]
public IActionResult DogConfigUploader([FromForm] IFormFile jSonFile){
    ...
}

[HttpPost]
[RequestSizeLimit(4000000)] //4Mb -> set this value "dynamically" from appsettings.json
[RequestFormLimits(MultipartBodyLengthLimit = 4000000)]
public IActionResult RabbitConfigUploader([FromForm] IFormFile jSonFile){
    ...
}

(I know, if I change the value in appsettings I have to restart the IIS, but this is better, than recompile the file.)

Upvotes: 1

Views: 1844

Answers (1)

Maxim Zabolotskikh
Maxim Zabolotskikh

Reputation: 3367

C# attribute is a compile-time construct, which means that all attribute parameters must be known at compile time. appsettings.json is a run-time thing, because it is loaded when the application starts. At this point the values for attributes must have already been set. So, the short answer, you cannot do this.

The long answer would be to use some kind of code generation tool. E.g. you could define your API in Swagger and let the C# code be generated with SwaggerCode Gen. The templates you can edit, and you could read out values from appsettings. This would require quite some work and is beyond the scope of this answer.

Here is a nice discussion specifically on the request size limit. You could probably use middleware to achieve what you want.

Edit:

In a middleware:

void MyMiddleware(/*inject settings*/){}

public async Task Invoke(HttpContext httpContext)
{
  var limit = SOME_LIMIT_FROM_SETTINGS;
  var path = httpContext.Request.Path;
  if (path.IsThisAndThat()){
    limit = ANOTHER_LIMIT_FROM_SETTINGS;
  }

  if (httpContext.Request.ContentLength > limit)
  {
    throw ... ;    
  }
}

Upvotes: 1

Related Questions