It never takes long when throwing together toy examples with these kinds of APIs to introduce a security risk:

    var uploads = Path.Combine(uploadsPath, file.FileName);
Where file.FileName appears to be drawn from the content-disposition header of the request. MS’s own asp.net docs on file uploads say:

“Use a safe file name determined by the app. Don't use a file name provided by the user or the untrusted file name of the uploaded file.”

I’m always wary of APIs designed to look good in a DevRel evangelist’s presentation, to show how you can do something in ‘just a few lines of code’, when the reality is that actual applications will need to deal with a bunch more concerns anyway and this terse little API is not going to make one jot of difference to the essential complexity you’re trying to express.

Whether you have a node express style server where you’re able to declare all your controller mappings in-line using lambdas, or a spring style router where controllers are in separate classes and methods makes no real difference to the fact you still have to write the controller body, and in any real application it is not going to be handling everything from request body handling to file system operations in one place anyway.

At least when the controllers are all classes I can unit test them.

> At least when the controllers are all classes I can unit test them.

I was always having great difficulty testing ASP.NET MVC controllers given the use of completely closed off, cyclical dependency, sealed class, properties like HttpContext.

Helper libraries made it somewhat easier to set them up but they were always heavy tests as a direct result of the large object graph needed.

But why? generally you don't test controllers directly.

You test "service"/"handler" classes that handle those requests.

If you want to test controllers, then you write E2E tests that send HTTP requests

Here's some example of how it might look like

https://docs.microsoft.com/en-us/aspnet/core/test/integratio...

If there's any critical behavior you're reliant on the controller (and, in frameworks like this, its attribute-driven configuration) to provide for you - throwing exceptions for bad requests, authentication or authorization, returning particular cache headers for particular response cases... I'd recommend looking for some way to write tests that, in isolation, go some way to let you assert those behaviors.

Don't bother writing the testcase that asserts that if the controller is called with a valid body, it calls the right service and passes on the request data. Write the testcase that asserts that if it's called with a body that's way too big that it throws the appropriate 400 exception, though.

One of the biggest problems with web frameworks which let you configure a lot of stuff like caching, auth and parameter validation using attributes, DI, or magic syntax, is that often the only way you can verify those behaviors are in place is with integration tests. And integration tests for failure modes are hard to write, so they don't get written. Which means it's easy to deploy a service which, say, is supposed to respond with stale cached data if a dependency is unavailable - but it actually doesn't because nobody was able to express a test case that verified that the controller caching attributes actually work the way they thought it did.

For Selenium tests I've been setting up an actual instance of application in test with different Startup (e.g sqlite instead of real database) and running at different port

This way you can test those fancy things, but I agree it's kinda "hard" to get it working for the first time

and wasteful. Starting up selenium et al is painfully slow compared to tests that run in

While I do agree, then you don't have to run Selenium tests on your PC, but let it be done by e.g ci/cd

Also depends how many pages do you want to test with Selenium - if you want to test e.g 5 pages, then it'll be fast enough I guess.

There are a few tricks/configurations that make Selenium significantly faster - https://stackoverflow.com/a/57720610

A lot of is also on how do you write your "testing infrastructure" - maybe you could reuse engine/browser instance? execute tests parallelly?

There's also alternative to Selenium by Microsoft: https://github.com/microsoft/playwright

AFAIK it's way more reliable than Selenium (false errors)

__________

Overall you can still start application inside tests with different startup, without Selenium and send http requests, so you'll have end-to-end tests done fast.