413 request entity too large - Web API - asp.net

I'm running into a 413 issue while trying to send data from my web application (.netfx 4.6.1) to my web api (.net core 3.1). In the code below, I send a list over containing byte data of images along with additional data needed to build a file. The expected output is to return a byte array containing the new file. Unfortunately when sending the request I receive an error: Response status code does not indicate success: 413 (Request Entity Too Large).
The error only seems to occur when the file is large to begin with, which makes sense. The research I've done seems to point to settings in IIS, the main ones being maxAllowedContentLength, maxRequestLength, and uploadReadAheadSize. I've tried increasing these values to ones more suited to this process but nothing seems to work. I've adjusted them for both the web application and the web api, as I was not sure which one was causing the problem.
Where does the problem lie? In the application, the API, or both? Is there an additional setting I'm missing to allow an increased size? Is there an issue with how I'm sending the request? Any help is appreciated.
public static async Task<byte[]> CreatePdfFromImageFilesAsync(List<ImageFile> imageFiles)
{
var list = new List<dynamic>();
foreach (var item in imageFiles)
{
list.Add(new
{
Data = Convert.ToBase64String(item.Bytes),
PageOrder = item.PageOrder,
Rotation = item.Rotation,
Type = "PDF"
});
}
var response = _client.PostAsJsonAsync($"{FileCreatorAPI}/api/files/CreateFileFromMultiple", list).Result;
var result = response.EnsureSuccessStatusCode();
var bytes = await result.Content.ReadAsAsync<byte[]>();
return bytes;
}

Below changes worked for me
// If using Kestrel:
.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
//options.Limits.MaxRequestBodySize = null; --did not worked
options.Limits.MaxRequestBodySize = int.MaxValue;
})
// If using IIS:
.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
//options.MaxRequestBodySize = null;
options.MaxRequestBodySize = int.MaxValue;
});
create web.config file and add following configuration
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483648" />
</requestFiltering>
</security>
</system.webServer>
</configuration>

Can you check that attribute https://github.com/aspnet/Announcements/issues/267 ?
Using
[RequestSizeLimit(100_000_000)]
on your controller entry point, or more globally setting it this way:
.UseKestrel(options =>
{
options.Limits.MaxRequestBodySize = null;
EDIT: article from MS: https://dotnet.microsoft.com/download/dotnet-core

I think the problem is on the server. The server is terminating the request because it exceeds it's configured maximum allowable request size.
Which server are you using?
For Nginx users, the directive which determines what the allowable HTTP request size can be is client_max_body_size, the default maximum allowable request size is 1MB.
The limit in Apache is set via the LimitRequestBody directive and defaults to 0 (meaning unlimited) to 2147483647 (2GB).
Check out this article on how you can fix it if you are using any of those two servers.

Related

How to increase the request size limit using minimal api with .NET 6?

I have an endpoint to upload videos
app.MapPost("/video/upload", async (HttpRequest request) =>
It works with small videos but when I try to upload a video of larger size I get an error saying that I exceeded the allowed size
We can configure kestrel through the builder value and specify the max request body size
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(o => o.Limits.MaxRequestBodySize = null);
null means that there is no limit.
You can use IHttpMaxRequestBodySizeFeature
async (HttpRequest request) =>
{
var bodySizeFeature =
request.HttpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
if (bodySizeFeature is not null)
{
bodySizeFeature.MaxRequestBodySize = 10; // set limit or null for unlimited
}
// process request
}
This can be configured in the web.config file.
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
This will set the limit to 1GB

asp.net web service maximum json input length has been exceeded

I got a webserver in .net working with Nancyfx. I have a route that has to upload an image, this image is sent from a client in json byte64 encoded, along with other attributes. When I try to bind the incoming json with my model, I got the next exception: "Maximum JSON input length has been exceeded."
Something like this:
Post["/Upload", true] = async(_, ctx) =>
{
UploadModel model = null;
model = this.Bind<UploadModel >();
.
.
.
}
I've read that changing the value of "maxJsonLength" in my web.config handles this issue, but when i set a higher value to it, there's no effect:
<scripting>
<webServices>
<jsonSerialization maxJsonLength="50000000"/>
</webServices>
</scripting>
Along with the maxRequestLength:
<httpRuntime targetFramework="4.5" maxRequestLength="1000000"/>
For some smaller pictures (5KB, 50KB) there's no problem in binding, but when I send pictures with sizes of 144KB and up, it gives me the error in concern.
Any thoughts? If I missed some relevant information, just ask me
Never mind guys, I just found the answer:
In the nancy documentation it says "if you encounter the Nancy.Json.JsonSettings.MaxJsonLength Exceeded error because your payload is too high, change that limit in your Bootsrapper ..."
So i did it:
public class Bootstrapper : DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
Nancy.Json.JsonSettings.MaxJsonLength = int.MaxValue;
}
}
Now, no more MaxJsonLength errors, hope this helps to somebody in the future!

Apply file upload size restriction on server side in asp.net C#

I am applying file upload size restriction, that user can't upload files more than 30 MB, and give him message if he exceeds the limit.
I am using following code.
if (fileUpload.HasFile)
{
if (fileUpload.PostedFile.ContentLength < 30 * 1024 * 1024) // 30 MB
{
if (fileUpload.FileName != null && fileUpload.FileName != "")
{
UploadFile(fileUpload, "flv,mp3", out videoFileName, out uploadError);
if (uploadError != "")
{
lblMessage.Visible = true;
lblMessage.Text = uploadError;
return false;
}
}
}
else
{
lblMessage.Visible = true;
lblMessage.Text = "File size exceeds the Limits. Please try uploading smaller size file.";
return false;
}
}
This code works fine in Visual Studio, but when I deploy the application on iis, it doesn't give me any message if I give more then 30 MB file, and directly upload the file.
where I am doing wrong.
Regards,
Kash
Have you used the standard maxRequestLength config property? It may well be that it's not suitable for your needs but it will work better in not utilising resources one the file limit is reached.
For an explanantion about how to handle the error see A better way of handling maxRequestLength exceptions
<system.web>
<httpRuntime maxRequestLength="31457280" executionTimeout="360"/>
</system.web>
When running under IIS7 You can set the file upload size limit like this in web.config file
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="10485760"/>
</requestFiltering>
</security> </system.webServer>
with such a code, it looks it works that way, I mean you code will execute only if the full content been post to the server. You need some extra work to verify the size on client side, or use some third party plugins like uploadify
You can check the size of the uploaded file only after the upload is complete. Check this link http://forums.asp.net/t/55127.aspx

Does anyone know if the crossdomain policy file at salesforce.com has changed?

Suddenly my Flex Apps can no longer connect to salesforce.com via its API, I am getting a security sandbox violation. Login credentials are correct, I have tried them via a different means, and I have obfuscated them below.
This was working fine earlier today and I have not been coding since then.
Anyone else come across this or know what's going on?
Here is the exception returned to my app
Method name is: login
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer connected.
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer sending message 'B89E5879-D7F7-E91E-2082-BBEE231054DD'
'direct_http_channel' channel sending message:
(mx.messaging.messages::HTTPRequestMessage)#0
body = "<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/"><se:Header xmlns:sfns="urn:partner.soap.sforce.com"/><se:Body><login xmlns="urn:partner.soap.sforce.com" xmlns:ns1="sobject.partner.soap.sforce.com"><username>simon.palmer#***.com</username><password>***</password></login></se:Body></se:Envelope>"
clientId = (null)
contentType = "text/xml; charset=UTF-8"
destination = "DefaultHTTPS"
headers = (Object)#1
httpHeaders = (Object)#2
Accept = "text/xml"
SOAPAction = """"
X-Salesforce-No-500-SC = "true"
messageId = "B89E5879-D7F7-E91E-2082-BBEE231054DD"
method = "POST"
recordHeaders = false
timestamp = 0
timeToLive = 0
url = "https://www.salesforce.com/services/Soap/u/11.0"
Method name is: login
*** Security Sandbox Violation ***
Connection to https://www.salesforce.com/services/Soap/u/11.0 halted - not permitted from https://localhost/pm_server/pm/pm-debug.swf
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer acknowledge of 'B89E5879-D7F7-E91E-2082-BBEE231054DD'.
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer fault for 'B89E5879-D7F7-E91E-2082-BBEE231054DD'.
Comunication Error : Channel.Security.Error : Security error accessing url : Destination: DefaultHTTPS
Error: Request for resource at https://www.salesforce.com/services/Soap/u/11.0 by requestor from https://localhost/pm_server/pm/pm-debug.swf is denied due to lack of policy file permissions.
You have to make sure to load the policy from the /services tree, the default policy at the root won't help you. You need to load this policy https://www.salesforce.com/services/crossdomain.xml
The solution to this problem was to set the server protocol and url as follows:
apex = new Connection();
apex.serverUrl = "https://na3.salesforce.com/services/Soap/u/14.0";
apex.protocol = "https";
However, this seems to create a secondary issue of users being locked out, so the issue of non-connectivity remains.
Update: salesforce.com have acknowledged a bug. See my other related post.
Did you recently upgrade to flash player 10? Flash player 10 changes the way policy files work to some degree, and the crossdomain.xml file needs to be updated to address this. In short, Salesforce.com probably isn't prepared for users upgrading to Flash Player 10 yet.
I resolve this issue accessing to the Flash Player Configuration Panel(I just recommend it in a development environment), in the "Global Security" tab, select Always Allow.
Regards.
I am uploading a file from flex to Google docs. Everything is working in the local file however, when we upload the SWF file as S-controls in Salesforce (sandbox), an error appears upon connecting to Google. Please see error below:
Error:[FaultEvent fault=[RPC Fault faultString="Security error accessing url"
faultCode="Channel.Security.Error" faultDetail="Destination: DefaultHTTPS"]
messageId="1F812836-1318-B845-AC01-F51AB1D11518" type="fault" bubbles=false
cancelable=true eventPhase=2]
We tried the following solutions below but nothing seems to work:
FLEX:
- Add the crossdomain.xml in the bin-debug folder: below is the content of the cross domain policy.
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" secure="false" />
<allow-http-request-headers-from domain="*" headers="*" secure="false" />
</cross-domain-policy>
Used flash.system.security.allowinsecuredomain/allowdomain(“*”) in the initialization.
Also tried in the connection.protocol set to http
Salesforce:
Disabled the protocol security in the remote site settings
o Setup -> Administration Setup -> Security Controls -> Remote Site Settings
 URL: http://www.google.com.ph
There’s no problem in connection to Salesforce but upon initialization of the uploading page the security error will appear specifically in the onErrorFault function. Below are code snippets:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="534" height="462" verticalScrollPolicy="off" horizontalScrollPolicy="off"
creationComplete="init()" showCloseButton="true" close="{this.closeWindow(event)}" roundedBottomCorners="true">
<mx:Script>
<![CDATA[
private function init():void{
Security.allowInsecureDomain("*");
//<salesforce:Connection id="apex" sendRequest="sendRequestListener(event)" serverUrl="http://www.salesforce.com/services/Soap/u/10.0" protocol="http"/>
RESTProxyTest();
send_data();
arrAddedFiles = new Array();
this.uploadGrid.dataProvider= this.acFiles;
this.title = "Attachment: "+this.selectedTimeSheetDetail.Project.label;
}
public function RESTProxyTest():void
{
_conn = new NetConnection();
_conn.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
_conn.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
_conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
_conn.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
_conn.objectEncoding = ObjectEncoding.AMF3;
_conn.connect(_url);
_responder = new Responder(onResult, onFault);
}
private function send_data():void {
userRequest.url = getLoginURL();
userRequest.addEventListener(ResultEvent.RESULT, httpResult);
userRequest.addEventListener(FaultEvent.FAULT, onErrorFault);
userRequest.send();
}
private function onErrorFault(obj:FaultEvent):void
{
Alert.show("Error:"+obj.toString());
}
private function httpResult(obj:ResultEvent):void
{
trace(obj.toString());
var result:String = obj.result as String;
var pos:int = result.lastIndexOf("Auth=");
var auth:String = result.substr(pos + 5);
txtAuth.text = StringUtil.trim(auth);
placeCall();
}
protected function placeCall():void
{
trace("placeCall");
var headers:Array = ["Authorization: " + "GoogleLogin auth=" + StringUtil.trim(txtAuth.text)];
var postVars:Array = [];
var uri:String = "http://docs.google.com/feeds/documents/private/full?showfolders=true";
_conn.call("RESTProxy.request", _responder, uri, "get", new Array(), postVars, headers);
}
private function getLoginURL():String
{
var url:String = 'https://www.google.com/accounts/ClientLogin?accountType=HOSTED_OR_GOOGLE&' +
'Email=' + this.session.config.gmail + '&' +
'Passwd=' + this.session.config.password + '&service=writely';
return url;
}
]]>
</mx:Script>
<mx:HTTPService id="userRequest" useProxy="false" method="POST" contentType="application/x-www-form-urlencoded" showBusyCursor="true"/>

IIS 7.0 503 errors with generic handler (.ashx) implementing IHttpAsyncHandler

I'm running into some performance issues using a generic handler that implements IHttpAsyncHandler. At its simplest, the handler receives a GET request, and 20 seconds later ends the response after writing '< timeout / >' to the response.
When hammering the .ashx with 10000-20000 simultaneous requests, it fails with 503 server unavailable after precisely 5000 requests. When switching to synchronous mode, and ending the request immediately, the problem goes away.
I've tinkered with a number of settings, yet the only thing I've managed to acheive is lower the request threshold at which this error occurs.
Here's a rundown of the settings I've toyed with:
machine.config:
<configuration>
...
<system.web>
...
<processModel enable="true" requestQueueLimit="10000"/>
...
web.config:
<configuration>
...
<system.web>
...
<httpRuntime enable="true" appRequestQueueLimit="10000"/>
...
IIS Manager > ApplicationPools > Advanced Settings
Queue Length : 65535
Although I can't be sure, it seems like these settings work good and fine if the requests are synchronous, but when async, I can't seem to get beyond exactly 5000 requests before the server starts telling me to go away. If I set things lower (can't remember exactly which setting that would be from the above, but I've tried them all), then the 503 count goes up accordingly, but I can never stop it happening beyond 5000 when under serious load.
It seems that there a a number of settings scattered in a myriad of places that might affect this, but the 5000 seems fairly set in stone. I see here that appRequestQueueLimit cannot exceed 5000, but can find no further info about this, and wonder if this is misinformation.
Is there any kind of "flood-control" setting in IIS that might be limiting a single host to no more than 5000 requests? How can I get IIS to handle more that 5000 concurrent asynchronous requests?
Edit2: Are there any counters or other indicators of which limit might be being exceeded, and how would I investigate further?
Edit: Here's the loadgenerator code:
using System;
using System.Net;
using System.Threading;
namespace HammerTime
{
class Program
{
private static int counter = 0;
static void Main(string[] args)
{
var limit = 5000;
ServicePointManager.DefaultConnectionLimit=limit;
for (int i = 0; i < limit;++i )
{
StartWebRequest(i.ToString());
}
Console.ReadLine();
}
private static void StartWebRequest(string channelId)
{
string uri = "http://spender2008/test/Test.ashx?channel="+channelId;
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(uri);
request.BeginGetResponse(responseHandler, request);
}
private static void responseHandler(IAsyncResult ar)
{
try
{
HttpWebRequest state = (HttpWebRequest)ar.AsyncState;
HttpWebResponse response = (HttpWebResponse)state.EndGetResponse(ar);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine(Interlocked.Increment(ref counter));
}
}
}
}
OK. Fixed... many thanks to this post for clearing up a few details.
To eliminate the 503 errors required 3 different config changes:
machine.config:
<configuration>
...
<system.web>
...
<processModel enable="true" requestQueueLimit="100000"/>
IIS Manager > ApplicationPools > Advanced Settings
Queue Length : 65535
and finally (the missing piece of the puzzle), the command line:
appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000
The web.config setting mentioned in the main post was irrelevant.
10000 concurrent connections, no problems. Thanks for help!

Resources