【问题标题】:Long json strings truncated when returned via .net API通过 .net API 返回时,长 json 字符串被截断
【发布时间】:2019-04-11 19:20:40
【问题描述】:

我有一个使用 FOR JSON 返回 json 的 SQL Server 存储过程。如果我在 SQL 中调用 proc,它会正确返回,并且可以使用 jsonlint 之类的东西来验证输出。但是,proc 是从 .net API 层调用的,当 json 很长时,它似乎会截断从 proc 获取的字符串,因此具有无效的 json。如果我减少返回的数据量,我会通过 API 获得一个有效的 json 字符串,但如果它超过一定数量的字符,它就会被截断。

这个过程的结果很好:

{"APIResult":[{"ID":200,"Status_Message":"Success","User_Message":"Success","OperatingCountries":[{"Country_Name":"Mexico","ISO_Alpha2":"MX","ISO_Alpha3":"MEX","UN_Code":"484","Legal_Age":18,"Default_Language":"es"},{"Country_Name":"United States of America","ISO_Alpha2":"US","ISO_Alpha3":"USA","UN_Code":"840","Legal_Age":21,"Default_Language":"en-us"}]}]}

但是这个结果,不是:

{"APIResult":[{"ID":200,"Status_Message":"Success","User_Message":"Success","OperatingCountries":[{"Country_Name":"Afghanistan","ISO_Alpha2":"AF","ISO_Alpha3":"AFG","UN_Code":"004","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Angola","ISO_Alpha2":"AO","ISO_Alpha3":"AGO","UN_Code":"024","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Albania","ISO_Alpha2":"AL","ISO_Alpha3":"ALB","UN_Code":"008","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Andorra","ISO_Alpha2":"AD","ISO_Alpha3":"AND","UN_Code":"020","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Argentina","ISO_Alpha2":"AR","ISO_Alpha3":"ARG","UN_Code":"032","Legal_Age":18,"Default_Language":"es"},{"Country_Name":"Armenia","ISO_Alpha2":"AM","ISO_Alpha3":"ARM","UN_Code":"051","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"American Samoa","ISO_Alpha2":"AS","ISO_Alpha3":"ASM","UN_Code":"016","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Antarctica","ISO_Alpha2":"AQ","ISO_Alpha3":"ATA","UN_Code":"010","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Antigua and Barbuda","ISO_Alpha2":"AG","ISO_Alpha3":"ATG","UN_Code":"028","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Australia","ISO_Alpha2":"AU","ISO_Alpha3":"AUS","UN_Code":"036","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Austria","ISO_Alpha2":"AT","ISO_Alpha3":"AUT","UN_Code":"040","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Azerbaijan","ISO_Alpha2":"AZ","ISO_Alpha3":"AZE","UN_Code":"031","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Belgium","ISO_Alpha2":"BE","ISO_Alpha3":"BEL","UN_Code":"056","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bangladesh","ISO_Alpha2":"BD","ISO_Alpha3":"BGD","UN_Code":"050","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bahrain","ISO_Alpha2":"BH","ISO_Alpha3":"BHR","UN_Code":"048","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bahamas","ISO_Alpha2":"BS","ISO_Alpha3":"BHS","UN_Code":"044","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bosnia and Herzegovina","ISO_Alpha2":"BA","ISO_Alpha3":"BIH","UN_Code":"070","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bermuda","ISO_Alpha2":"BM","ISO_Alpha3":"BMU","UN_Code":"060","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bolivia","ISO_Alpha2":"BO","ISO_Alpha3":"BOL","UN_Code":"068","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Barbados","ISO_Alpha2":"BB","ISO_Alpha3":"BRB","UN_Code":"052","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bhutan","ISO_Alpha2":"BT","ISO_Alpha3":"BTN","UN_Code":"064","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Bouvet Island","ISO_Alpha2":"BV","ISO_Alpha3":"BVT","UN_Code":"074","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Botswana","ISO_Alpha2":"BW","ISO_Alpha3":"BWA","UN_Code":"072","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Algeria","ISO_Alpha2":"DZ","ISO_Alpha3":"DZA","UN_Code":"012","Legal_Age":18,"Default_Language":"en-gb"},{"Country_Name":"Mexico","ISO_Alpha2":"MX","ISO_Alpha3":"MEX","UN_Code":"484","Legal_Age":18,"Default_Language":"es"},{"Country_Name":"United States of  America","ISO_Alpha2":"US","ISO_Alpha3":"USA","UN_Code":"840","Legal_Age":21,"Default_Language":"en-us"}]}]}

这是API项目中的代码:

cmd2 = new SqlCommand("GetOperatingCountries");
cmd2.Connection = conn2;
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandTimeout = 1000;

SqlParameter param = new SqlParameter();
param.ParameterName = "DefaultLanguage";
if (DefaultLanguage.ToUpper() == "NULL")
{ param.Value = DBNull.Value; }
else { param.Value = DefaultLanguage; }
param.SqlDbType = SqlDbType.VarChar;
param.IsNullable = true;
cmd2.Parameters.Add(param);

DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd2);
da.Fill(ds);
message = ds.Tables[0].Rows[0][0].ToString();

var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(message, Encoding.UTF8, "application/json");
return ResponseMessage(response);

第一个示例在 postman 中生成了不错的 json,但第二个示例只返回了未格式化的截断字符串。

谁能解释一下我做错了什么?

【问题讨论】:

  • 它们是否会被截断为 4,000 或 8,000 个字符?
  • 第二个示例中没有截断或无效的 JSON。您的意思是您希望返回更多国家/地区记录吗?
  • 您的 web.config 中的 maxJsonLength 是什么?
  • 看起来您同时获得了 en-gb 和 en-us。因此,请确保在您的请求中指定 en-us。您可以使用像 wireshark 或 fiddler 这样的嗅探器来检查请求,以确保您在请求中发送国家/地区语言。
  • 为什么要使用 Rows[0][0]?

标签: c# json sql-server string


【解决方案1】:

对于冗长的结果,返回的 JSON 可能会以多行的形式返回。

参见Format Query Results as JSON with FOR JSON(“FOR JSON 子句的输出”部分)和Use FOR JSON output in a C# client app

var queryWithForJson = "SELECT ... FOR JSON";
var conn = new SqlConnection("<connection string>");
var cmd = new SqlCommand(queryWithForJson, conn);
conn.Open();
var jsonResult = new StringBuilder();
var reader = cmd.ExecuteReader();
if (!reader.HasRows)
{
    jsonResult.Append("[]");
}
else
{
    while (reader.Read())
    {
        jsonResult.Append(reader.GetValue(0).ToString());
    }
}

【讨论】:

  • 好的。这行得通。我必须重构所有控制器才能使用它,但它确实提供了正确的结果,感谢 kobik
【解决方案2】:

尝试设置最大请求长度或 maxAllowedContentLength

 <httpRuntime targetFramework="4.5" maxRequestLength="65536" />

<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="52428800" />
  </requestFiltering>
</security>

【讨论】:

  • 这些行在 web.config 中的什么位置?可以指点一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多