如何将适度大量的数据传递到我的 Web API 应用程序?
How can I pass a moderately large volume of data to my Web API app?
我在 Web 中获得了这段代码 API 控制器:
[Route("{unit}/{begindate}/{enddate}")]
[HttpPost]
public void Post(string unit, string begindate, string enddate,
[FromBody] string stringifiedjsondata)
{
List<ProduceUsageSPResults> _produceUsageList = JsonConvert.DeserializeObject<List<ProduceUsageSPResults>>(stringifiedjsondata);
string _unit = unit;
string _begindate = String.Format("{0}01", HyphenizeYYYYMM(begindate));
string _enddate = GetEndOfMonthFor(enddate);
string appDataFolder =
HttpContext.Current.Server.MapPath("~/App_Data/");
string htmlStr = ConvertProduceUsageListToHtml(_produceUsageList);
string htmlFilename = string.Format("produceUsage_{0}_{1}_{2}.html",
_unit, _begindate, _enddate);
string fullPath = Path.Combine(appDataFolder, htmlFilename);
File.WriteAllText(fullPath, htmlStr);
}
当通过“[FromBody]”参数从客户端(Winforms 应用程序)传递少量(人为的)数据时,它工作正常,如下所示:
private async Task SaveProduceUsageFileOnServer(string beginMonth, string beginYear, string endMonth, string endYear, DataTable _dtUsage)
{
string beginRange = String.Format("{0}{1}", beginYear, beginMonth);
string endRange = String.Format("{0}{1}", endYear, endMonth);
HttpClient client = new HttpClient {BaseAddress = new Uri("http://localhost:42176")};
string dataAsJson = "[{\"ItemDescription\": \"DUCKBILLS, GRAMPS-EIER 70CT 42#\",\"PackagesMonth1\": 1467}]";
//string dataAsJson = JsonConvert.SerializeObject(_dtUsage);
String uriToCall = String.Format("/api/produceusage/{0}/{1}/{2}", _unit, beginRange, endRange);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("", dataAsJson)
});
HttpResponseMessage response = await client.PostAsync(uriToCall, content);
}
但是,如果我反转对 dataAsJson 赋值的注释,以便它发送真实数据,如下所示:
//string dataAsJson = "[{\"ItemDescription\": \"DUCKBILLS, GRAMPS-EIER 70CT 42#\",\"PackagesMonth1\": 1467}]";
string dataAsJson = JsonConvert.SerializeObject(_dtUsage);
...失败;没有错误信息;使用 JsonConvert.SerializeObject() 方法将 DataTable (_dtUsage) 序列化为 json;只是有 "lot" of 数据(几千条记录)。永远不会到达客户端对 PostAsync() 的调用,因此永远不会到达服务器的 Post 方法。
是否有一种变通方法可以在发送的数据量不仅仅是微不足道的情况下使此操作成功?我真的不喜欢通过网络传递那么多数据(目前客户端和服务器都是 运行 本地,但考虑一下部署后的情况),但另一种选择是从两者执行相同的存储过程客户端(在那里生成 Excel 电子表格文件)和来自服务器(将数据转换为 HTML)。这似乎是 "Catch-22" 情况之一 ("impounded if I do, sequestered if I don't")。
更新
测试 user3093073 的想法,我将其添加到 Web.config 的 system.webServer 部分:
<security>
<requestFiltering>
<requestLimits>
<headerLimits>
<add header="Content-type" sizeLimit="10000000" />
</headerLimits>
</requestLimits>
</requestFiltering>
</security>
(根据我发现的 here,但它仍然无法正常工作...
更新 2
接近用户user3093073的回答,我也试过这个:
<requestFiltering>
<requestLimits maxAllowedContentLength="10000000">
<!--<headerLimits>
<add header="Content-type" sizeLimit="100" />
</headerLimits>-->
</requestLimits>
</requestFiltering>
...也无济于事。
更新 3
请注意,我将上面的代码放在站点的每个 Web.config 文件中,即:
The Web.config file below the \[ProjectName]\Views folder
The Web.config file below the \[ProjectName] folder
The two Web.config files below the \[ProjectName]\Web.config file, namely "Web.Debug.config" and "Web.Release.config"
...或者,另一种查看位置的方式:
\PlatypusReports\Web.config
\PlatypusReports\Web.config\Web.Debug.config
\PlatypusReports\Web.config\Web.Release.config
\PlatypusReports\Views\Webconfig
更新 4
在离开这个几天又回到它之后,现在对我来说很明显,我试图传递的 "real" 数据与 phony/test 数据是不同的动物, 有效。
测试数据是简单键值对的集合。然而,真实数据要复杂得多。因此,当我尝试将复杂的数据转换为简单的 KeyValuePair 时,麻烦肯定会接踵而至。所以不是这个:
new KeyValuePair<string, string>("", dataAsJson)
...我需要这样的东西:
new List<DeliveryPerformanceClass>("", dataAsJson)
...但这也不起作用;我收到几个编译错误,例如,“'System.Collections.Generic.List' 不包含采用 2 个参数的构造函数'”
如果我删除第一个参数,那么它是:
new List<DeliveryPerformanceClass>(dataAsJson)
...我收到其他编译错误,例如,“参数 1:无法从 'string' 转换为 'int'”
您必须设置 IIS 才能接受大文件。默认情况下它只有 4MB 左右。检查你的 web.config。这是 2GB 的设置:
<requestLimits maxAllowedContentLength="2147483648" />
我相信既然你已经指定了<requestFiltering>
设置,那么你还需要设置maxRequestLength
。正如@brewsky 提到的,默认情况下它只有 4MB。检查你的 web.config。这是为 2GB
设置的
<configuration>
<system.web>
<httpRuntime maxRequestLength="2147483648" />
</system.web>
</configuration>
这个 SO answer 似乎解决了类似的问题。
我在 Web 中获得了这段代码 API 控制器:
[Route("{unit}/{begindate}/{enddate}")]
[HttpPost]
public void Post(string unit, string begindate, string enddate,
[FromBody] string stringifiedjsondata)
{
List<ProduceUsageSPResults> _produceUsageList = JsonConvert.DeserializeObject<List<ProduceUsageSPResults>>(stringifiedjsondata);
string _unit = unit;
string _begindate = String.Format("{0}01", HyphenizeYYYYMM(begindate));
string _enddate = GetEndOfMonthFor(enddate);
string appDataFolder =
HttpContext.Current.Server.MapPath("~/App_Data/");
string htmlStr = ConvertProduceUsageListToHtml(_produceUsageList);
string htmlFilename = string.Format("produceUsage_{0}_{1}_{2}.html",
_unit, _begindate, _enddate);
string fullPath = Path.Combine(appDataFolder, htmlFilename);
File.WriteAllText(fullPath, htmlStr);
}
当通过“[FromBody]”参数从客户端(Winforms 应用程序)传递少量(人为的)数据时,它工作正常,如下所示:
private async Task SaveProduceUsageFileOnServer(string beginMonth, string beginYear, string endMonth, string endYear, DataTable _dtUsage)
{
string beginRange = String.Format("{0}{1}", beginYear, beginMonth);
string endRange = String.Format("{0}{1}", endYear, endMonth);
HttpClient client = new HttpClient {BaseAddress = new Uri("http://localhost:42176")};
string dataAsJson = "[{\"ItemDescription\": \"DUCKBILLS, GRAMPS-EIER 70CT 42#\",\"PackagesMonth1\": 1467}]";
//string dataAsJson = JsonConvert.SerializeObject(_dtUsage);
String uriToCall = String.Format("/api/produceusage/{0}/{1}/{2}", _unit, beginRange, endRange);
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("", dataAsJson)
});
HttpResponseMessage response = await client.PostAsync(uriToCall, content);
}
但是,如果我反转对 dataAsJson 赋值的注释,以便它发送真实数据,如下所示:
//string dataAsJson = "[{\"ItemDescription\": \"DUCKBILLS, GRAMPS-EIER 70CT 42#\",\"PackagesMonth1\": 1467}]";
string dataAsJson = JsonConvert.SerializeObject(_dtUsage);
...失败;没有错误信息;使用 JsonConvert.SerializeObject() 方法将 DataTable (_dtUsage) 序列化为 json;只是有 "lot" of 数据(几千条记录)。永远不会到达客户端对 PostAsync() 的调用,因此永远不会到达服务器的 Post 方法。
是否有一种变通方法可以在发送的数据量不仅仅是微不足道的情况下使此操作成功?我真的不喜欢通过网络传递那么多数据(目前客户端和服务器都是 运行 本地,但考虑一下部署后的情况),但另一种选择是从两者执行相同的存储过程客户端(在那里生成 Excel 电子表格文件)和来自服务器(将数据转换为 HTML)。这似乎是 "Catch-22" 情况之一 ("impounded if I do, sequestered if I don't")。
更新
测试 user3093073 的想法,我将其添加到 Web.config 的 system.webServer 部分:
<security>
<requestFiltering>
<requestLimits>
<headerLimits>
<add header="Content-type" sizeLimit="10000000" />
</headerLimits>
</requestLimits>
</requestFiltering>
</security>
(根据我发现的 here,但它仍然无法正常工作...
更新 2
接近用户user3093073的回答,我也试过这个:
<requestFiltering>
<requestLimits maxAllowedContentLength="10000000">
<!--<headerLimits>
<add header="Content-type" sizeLimit="100" />
</headerLimits>-->
</requestLimits>
</requestFiltering>
...也无济于事。
更新 3
请注意,我将上面的代码放在站点的每个 Web.config 文件中,即:
The Web.config file below the \[ProjectName]\Views folder
The Web.config file below the \[ProjectName] folder
The two Web.config files below the \[ProjectName]\Web.config file, namely "Web.Debug.config" and "Web.Release.config"
...或者,另一种查看位置的方式:
\PlatypusReports\Web.config
\PlatypusReports\Web.config\Web.Debug.config
\PlatypusReports\Web.config\Web.Release.config
\PlatypusReports\Views\Webconfig
更新 4
在离开这个几天又回到它之后,现在对我来说很明显,我试图传递的 "real" 数据与 phony/test 数据是不同的动物, 有效。
测试数据是简单键值对的集合。然而,真实数据要复杂得多。因此,当我尝试将复杂的数据转换为简单的 KeyValuePair 时,麻烦肯定会接踵而至。所以不是这个:
new KeyValuePair<string, string>("", dataAsJson)
...我需要这样的东西:
new List<DeliveryPerformanceClass>("", dataAsJson)
...但这也不起作用;我收到几个编译错误,例如,“'System.Collections.Generic.List' 不包含采用 2 个参数的构造函数'”
如果我删除第一个参数,那么它是:
new List<DeliveryPerformanceClass>(dataAsJson)
...我收到其他编译错误,例如,“参数 1:无法从 'string' 转换为 'int'”
您必须设置 IIS 才能接受大文件。默认情况下它只有 4MB 左右。检查你的 web.config。这是 2GB 的设置:
<requestLimits maxAllowedContentLength="2147483648" />
我相信既然你已经指定了<requestFiltering>
设置,那么你还需要设置maxRequestLength
。正如@brewsky 提到的,默认情况下它只有 4MB。检查你的 web.config。这是为 2GB
<configuration>
<system.web>
<httpRuntime maxRequestLength="2147483648" />
</system.web>
</configuration>
这个 SO answer 似乎解决了类似的问题。