IIS Express and Visual Studio 2019 - 413.1 - Request Entity Too Large - asp.net-core

I have a .Net Core 2.2 Service to which I am trying to submit a large-ish request payload (including several base-64 encoded files). Total size is just under 30mb. The controller immediately rejects with error 413.1 - Request Entity Too Large.
I have done a bit of research on the issue, but most solutions focus on modifying uploadReadAheadSize in the full version of IIS (but this is IIS express, running locally in VS), or modifying the web.config file (this .Net Core project does not have one).
The project is not going to be deployed in IIS, so I don't think the solutions I've found would work for me at that point either. How can I make this work locally for debugging purposes?

The default request body size limit is 28.6 MB for .NET Core >2.0
If you are not going to use IIS for your deployment and wanted to make it work for debugging purposes, you can use Kestrel and reset the maximum request body size restriction inside of your Program.cs as shown below
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options => { options.Limits.MaxRequestBodySize = null; });
You can know more about Kestrel's configuration options from here
Further, this change has been introduced as a breaking change in the version 2.0 of .NET Core. This announcement talks about the ways to perform this in MVC, Middleware and also globally like I showed above.

Related

CryptographicException when deploying IdentityServer4 solution with AddDeveloperSigningCredential to IIS

I have a working Auth service built on IdentityServer3 and .NET Framework. I'm in the process of building a new version of it on IdentityServer4 and ASP.NET Core. In this early stage in development, I'm still using AddDeveloperSigningCredential. When I deploy it to my local development box (Windows 10) in a console window, it runs fine. When I deploy it to IIS Express on my local development box, it gets the following error on startup:
UnauthorizedAccessException: Access to the path 'C:\Program Files\IIS Express\tempkey.rsa' is denied.
I don't really care if it runs in IIS Express (since it runs fine in a console window), but I include this information in case it is relevant to my problem.
When I deploy the solution to a remote server running IIS (Windows Server 2008 R2, IIS 7.5) it fails on startup with this error:
Application startup exception:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Object was not found
at System.Security.Cryptography.CngKeyLite.GenerateNewExportableKey(String algorithm, Int32 keySize)
at System.Security.Cryptography.RSAImplementation.RSACng.GetDuplicatedKeyHandle()
at System.Security.Cryptography.RSAImplementation.RSACng.ExportKeyBlob(Boolean includePrivateParameters)
at System.Security.Cryptography.RSAImplementation.RSACng.ExportParameters(Boolean includePrivateParameters)
at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderExtensionsCrypto.AddDeveloperSigningCredential(IIdentityServerBuilder builder, Boolean persistKey, String filename)
at Orvis.Authorization.Service.Startup.ConfigureServices(IServiceCollection services) in C:\Workspaces\Orvis\orvis-microservices\orvis-authorization\Orvis.Authorization.Service\Startup.cs:line 20
Will IdentityServer4 and, in particular AddDeveloperSigningCredential, work on Windows Server 2008 R2 and IIS 7.5 or do I need a newer development server? Or, if the age of the O/S is not the problem, what else might be causing this error?
Well I got this working. At some point along the way the symptom changed and I'm not sure why, but I'll recount here what I know.
I originally had the .AddDeveloperSigningCertficate call hard-coded in my startup code - like this:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetTestUsers());
That produced the WindowsCryptographicException on startup as noted in the original post. Following some updated IdentityServer4 documentation, I changed that to:
var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetTestUsers());
if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
else
{
throw new Exception("Need to configure key material");
}
Once I made sure my target server had the correct environment variable to define itself as a Development environment, I think that should have produced the same result. But instead it produced the access denied error that I'd seen earlier in my attempts to deploy locally to IIS Express.
Given that error, I was able to grant the IIS ApplicationPoolIdentity identity write access to c:\windows\system32\inetsrv, which is where it was trying to write the tempkey.rsa developer credential file. This article provides a good overview of ApplicationPoolIdentity and details on how to grant permissions to that identity for your app pool. Granting permissions to that system directory required first taking ownership of the directory.
With all of that done, my service is now running successfully with the developer signing credentials in IIS on my development server.

Deploying a .NET core 2 website on a windows 2008 R2 server

I'm currently working on a site project and I'm using .NET Core 2.
When I run my project locally everything works fine.
When I publish my site on the servers and I look in the publication folder I have the files. However when I call the URL of my site I have an error "HTTP Error 502.5 - Process Failure".
I read a lot of doc at the server configuration and this side everything seems ok. I think the concern comes from the config of my project, but I do not know too much or.
So if anyone has ever had this type of problem and if so, if there is a solution. I specify that I installed the core .NET bundle for Windows server.
Thanks.
For me this is usually one of two things. You forgot to build the app with .UseIISIntegration in Program.cs, or it's missing dependencies.
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseIISIntegration()
.Build();
If it's a dependency issue, you can be specific and define the platform you're publishing to in your .csproj, or you can just install the full SDK on the server. I typically go with the later because it makes my deploys smaller and I know I won't be missing something defined in the manifest.

Aurelia .NET Core - Browser sync not working on .NET Core

I followed this tutorial on how to use Aurelia/Aurelia CLI with .NET Core.
Changes that I had to make:
Had to target a specific version for Microsoft.DotNet.Watcher.Tools, (dotnet watch run command didn't work)
Changed aurelia.json => build => targets => output value from "." to "wwwroot/scripts", (port:9000 didn't work, errormessage: "Cannot GET / to the server", port 5000 served by .NET Core worked however).
tasks => run.js => browsersync => server => basedir value from ['.'] to ['./wwwroot'], (Fixed browser sync not working on port:9000, however still doesn't work on port:5000 served by .NET Core)
1. How can I make the Browser sync work on port:5000 served by .NET Core?
It must be something in the run.js file. I have tried:
let serve = gulp.series(
build,
done => {
browserSync({
open: false,
port: 9000,
logLevel: 'silent',
proxy: {
target: 'localhost:5000'
}
}, function(err, bs) {
let urls = bs.options.get('urls').toJS();
console.log(`Application Available At: ${urls.local}`);
console.log(`BrowserSync Available At: ${urls.ui}`);
done();
});
}
);
..with no success..
2. Does it matter if I develop on port:5000 or port:9000?
3. What's the point in hosting Aurelia in .NET Core?
Should I only use .NET Core for WepAPI etc?
I think you're going about this in a very unorthodox way.
Just keep going with what you have. The standard is to host the .NET Core project on port 5000 and Browser Sync on port 9000.
You can't host the .NET Core project and the Browser sync on the same port, and messing with the .NET Core project just to move Browser sync to port 5000 is just a lot of work for no benefit.
You develop an Aurelia application, whatever port you decide to host it on doesn't matter at all :)
I wanted to offer an alternative as most tutorials focus on developing on Node. Also, I personally like the MSFT ecosystem, and when I'm going live with any site, it's in Azure. So for me it makes more sense.
I recommend you use whatever technology that makes you productive and whatever makes sense regards to your choice of production environment.

InProcProxyFactory.CreateInstance called from WCF Service

I am trying to use the ServiceModelEx library from IDesign. When I try to call:
InProcFactory.CreateInstance();
from with in a WCF Service (basically calling WCF Service B from WCF Service A), I get the following error:
Could not find dynamic assembly
The code that is failing is:
internal static Assembly[] GetWebAssemblies()
{
Debug.Assert(IsWebProcess());
List<Assembly> assemblies = new List<Assembly>();
if(Assembly.GetEntryAssembly() != null)
{
throw new InvalidOperationException("Can only call in a web assembly");
}
foreach(ProcessModule module in Process.GetCurrentProcess().Modules)
{
assemblies.Add(Assembly.LoadFrom(module.FileName));
if (module.ModuleName.StartsWith("App_Code.") && module.ModuleName.EndsWith(".dll"))
{
assemblies.Add(Assembly.LoadFrom(module.FileName));
}
if (module.ModuleName.StartsWith("App_Web_") && module.ModuleName.EndsWith(".dll"))
{
assemblies.Add(Assembly.LoadFrom(module.FileName));
}
}
if (assemblies.Count == 0)
{
throw new InvalidOperationException("Could not find dynamic assembly");
}
return assemblies.ToArray();
}
The assemblies are not pre-fixed with App_Web or App_Code because this is not a web site or a web application (it is a WCF Service). The code does work, however, if I call it from a web site, web application or EXE. Is this by deisgn?
Maybe the modules you expect have simply not been loaded in this scenario.
That's the generic resolver falling over. It tries to do it's best to discover all assemblies that might have data contracts in them, but it's something of an arms race as different hosting environments (particularly IIS variants) popup. The introduction of dynamic code has also made life more difficult.
If you use the latest ServiceModelEx (SME) it has fixes to address this. Just make sure you use the latest .NET version (currently 4.6.1) in the download since the older .NET version downloads of SME (e.g. 4.0 and earlier) won't have these fixes. You can downgrade the .NET version (within limits) if needed. E.g. I took the 4.6.1 version down to 4.5.2.
Note: this is only needed if you're using data contract inheritance via the Generic Resolver. If you don't need this feature and it's causing you issues you can just comment out the offending code.

Performance in Service Stack vs IIS for serving files

We're using Service Stack for a web service API. We wrote a "get file" routine to fetch files rather than letting IIS serve the files directly, because we need server-side authentication logic.
We return a file from RestServiceBase<Foo>.OnGet by returning an IStreamWriter, which is implemented like this:
public void WriteTo(Stream responseStream)
{
Stream filedata = File.OpenRead(_filepath);
filedata.CopyTo(responseStream);
}
The problem: This is about 50% to 100% slower than IIS serving the file directly.
Am I returning a file from Service Stack incorrectly? Is there something I can do to speed this up?
Alternatively, is there some way I can plug our authentication scheme (which we want to be total stateless, so no caching credentials on a server machine) into IIS so that IIS calls our server in some way to authenticate each request then serves the file itself?
Native code vs Managed Code
IIS would use native code for serving static files and likely employs some aggressive in-memory caching to achieve its performance.
As ServiceStack is a .NET library that code is writing directly to ASP.NET's response stream so its harder to get any faster at streaming a file in managed .NET code. You could further increase performance by loading the file into memory and writing raw bytes instead.
Take advantage of HTTP Caching
Which is why if you have to do it managed code you should give your best efforts at taking advantage of HTTP Caching which is what we do in our StaticFileHandler - i.e. what ServiceStack uses to serve its static content, e.g css/js/html pages.
Register a Raw HttpHandler
Although ServiceStack's request pipeline is heavily optimized (i.e. doesn't add much overhead) you can still by-pass it by registering your own custom IHttpHandler and handle the raw ASP.NET request yourself - this will be the fastest option in .NET code, e.g:
SetConfig(new EndpointHostConfig {
RawHttpHandlers = { MiniProfilerHandler.MatchesRequest },
});
This is what the built-in MiniProfiler uses to serve its static content. MatchesRequest just takes a IHttpRequest to work out if it should handle the request (by returning a instance of IHttpHandler) or not (return null):
public static IHttpHandler MatchesRequest(IHttpRequest request)
{
var file = Path.GetFileNameWithoutExtension(request.PathInfo);
return file != null && file.StartsWith("ss-")
? new MiniProfilerHandler()
: null;
}
Other than that, the stand-alone version of ServiceStack (i.e. HttpListener host) should provide better raw thoughput than ASP.NET.
There is a penalty in the context switch of the IIS I/O thread to a thread on the CLR thread pool, if you set the (asp config) MaxConcurrentRequestsPerCPU to 0 your CLR code you should be able to mitigate that (might have other ramifications though)
see
http://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx
I don't know if windows allow for "zero copy":ing the file (never leaving the kernel mode and skipping buffer on socket to filehandle operation) But if that is supported IIS is definitely utilizing it (making it faster than CLR in user mode .. )