.NET 4.0 Web API Return JSON 没有转义字符
.NET 4.0 Web API Return JSON without escaping characters
我已经阅读了无数的问题和答案,但还没有看到任何解决问题的方法。
我正在使用 newtonsoft JSON 库,只是想从 table.
return 一些 JSON
所以在我的控制器中,我只是有(服务器和数据库详细信息为了隐私而空白):
public IHttpActionResult GetHelloWorld()
{
string JSONResult;
SqlConnection conn = new SqlConnection("Server=<servername>;Database=<dbname>;user=<username>;password=<password>");
DataTable table = new DataTable();
conn.Open();
SqlCommand cmd = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", conn);
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(table);
}
//System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
//List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
//Dictionary<string, object> row;
//foreach (DataRow dr in table.Rows)
//{
// row = new Dictionary<string, object>();
// foreach (DataColumn col in table.Columns)
// {
// row.Add(col.ColumnName, dr[col]);
// }
// rows.Add(row);
//}
//return Ok(serializer.Serialize(rows),);
JSONResult = JsonConvert.SerializeObject(table);
return Ok(JSONResult);
}
现在它 return 是我预期的结果集,但如果不对双引号进行转义,我根本无法将其设置为 return,因此数据如下所示:
"[{\"name\":\"Aaron's Hill\",\"latitude\":51.18276,\"longitude\":-0.63503},{\"name\":\"Abbas Combe\",\"latitude\":51.00113,\"longitude\":-2.42178},
现在我读过的许多答案只是简单地说它是因为您正在查看 IDE 中的结果。在我的例子中,这是不正确的,这是浏览器 window 中的输出(尝试了 IE 和 chrome),当你说给我看 JSON 输出时,甚至 fiddler 都会抱怨它说无效位置 3 的字符。
你会看到我已经注释掉了代码,这是我在此处找到的 returning JSON 的另一种方法,但它仍然转义了引号。不确定还可以尝试什么?
你不应该自己序列化对象!
您应该 return 一个 class 对象,它将被 ASP.NET 序列化。现在,ASP.NET 序列化了一个序列化对象 - 这就是为什么你得到转义引号的原因。
应该是这样的:
public IHttpActionResult GetHelloWorld()
{
SqlConnection conn = new SqlConnection("Server=<servername>;Database=<dbname>;user=<username>;password=<password>");
DataTable table = new DataTable();
conn.Open();
SqlCommand cmd = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", conn);
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(table);
}
return Ok(table); // DO NOT serialize
}
但是,returning DataTable
对象听起来不对 - 它不会被正确序列化。
您需要像这样 return 代表您的实体的自定义对象(仅作为示例,可能不起作用):
public IHttpActionResult GetHelloWorld()
{
List<YourCustomClass> result = new List<YourCustomClass>();
SqlConnection conn = new SqlConnection("Server=<servername>;Database=<dbname>;user=<username>;password=<password>");
conn.Open();
SqlCommand cmd = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", conn);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
result.Add(new YourCustomClass {
Name = (string)reader["name"],
Latitude = (decimal)reader["latitude"],
Longitude = (decimal)reader["longitude"]
});
}
return Ok(result);
}
展望未来,我可能建议您不要在 ASP.NET class 中进行 SQL 查询。 SQL 连接和查询属于数据访问层 (DAL) - 它应该存储在单独的逻辑层中 - 在单独的项目中,或者至少,在单独的 class 中。您可以使用存储库模式(它是一种模式吗?):
// Somewhere in a class library
public class Address
{
public string Name { get; set; }
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
}
public class AddressesRepository : IAddressesRepository
{
public Address[] ReadAll()
{
List<YourCustomClass> result = new List<YourCustomClass>();
var connection = SqlConnectionFactory.CreateAndOpenConnection();
var reader = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", connection).ExecuteReader();
while (reader.Read())
{
result.Add(new Address {
Name = (string)reader["name"],
Latitude = (decimal)reader["latitude"],
Longitude = (decimal)reader["longitude"]
});
}
return result;
}
}
// Somewhere in ASP.NET WebAPI
private IAddressesRepository _addressesRepository = new AddressesRepository();
public IHttpActionResult GetHelloWorld()
{
var data = _addressesRepository.ReadAll();
return Ok(data);
}
我建议阅读一些关于分层架构和 ASP.NET WebAPI 本身的书籍,以便获得所有基本 ASP.NET 问题的答案。
我已经阅读了无数的问题和答案,但还没有看到任何解决问题的方法。
我正在使用 newtonsoft JSON 库,只是想从 table.
return 一些 JSON所以在我的控制器中,我只是有(服务器和数据库详细信息为了隐私而空白):
public IHttpActionResult GetHelloWorld()
{
string JSONResult;
SqlConnection conn = new SqlConnection("Server=<servername>;Database=<dbname>;user=<username>;password=<password>");
DataTable table = new DataTable();
conn.Open();
SqlCommand cmd = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", conn);
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(table);
}
//System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
//List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
//Dictionary<string, object> row;
//foreach (DataRow dr in table.Rows)
//{
// row = new Dictionary<string, object>();
// foreach (DataColumn col in table.Columns)
// {
// row.Add(col.ColumnName, dr[col]);
// }
// rows.Add(row);
//}
//return Ok(serializer.Serialize(rows),);
JSONResult = JsonConvert.SerializeObject(table);
return Ok(JSONResult);
}
现在它 return 是我预期的结果集,但如果不对双引号进行转义,我根本无法将其设置为 return,因此数据如下所示:
"[{\"name\":\"Aaron's Hill\",\"latitude\":51.18276,\"longitude\":-0.63503},{\"name\":\"Abbas Combe\",\"latitude\":51.00113,\"longitude\":-2.42178},
现在我读过的许多答案只是简单地说它是因为您正在查看 IDE 中的结果。在我的例子中,这是不正确的,这是浏览器 window 中的输出(尝试了 IE 和 chrome),当你说给我看 JSON 输出时,甚至 fiddler 都会抱怨它说无效位置 3 的字符。
你会看到我已经注释掉了代码,这是我在此处找到的 returning JSON 的另一种方法,但它仍然转义了引号。不确定还可以尝试什么?
你不应该自己序列化对象!
您应该 return 一个 class 对象,它将被 ASP.NET 序列化。现在,ASP.NET 序列化了一个序列化对象 - 这就是为什么你得到转义引号的原因。
应该是这样的:
public IHttpActionResult GetHelloWorld()
{
SqlConnection conn = new SqlConnection("Server=<servername>;Database=<dbname>;user=<username>;password=<password>");
DataTable table = new DataTable();
conn.Open();
SqlCommand cmd = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", conn);
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(table);
}
return Ok(table); // DO NOT serialize
}
但是,returning DataTable
对象听起来不对 - 它不会被正确序列化。
您需要像这样 return 代表您的实体的自定义对象(仅作为示例,可能不起作用):
public IHttpActionResult GetHelloWorld()
{
List<YourCustomClass> result = new List<YourCustomClass>();
SqlConnection conn = new SqlConnection("Server=<servername>;Database=<dbname>;user=<username>;password=<password>");
conn.Open();
SqlCommand cmd = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", conn);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
result.Add(new YourCustomClass {
Name = (string)reader["name"],
Latitude = (decimal)reader["latitude"],
Longitude = (decimal)reader["longitude"]
});
}
return Ok(result);
}
展望未来,我可能建议您不要在 ASP.NET class 中进行 SQL 查询。 SQL 连接和查询属于数据访问层 (DAL) - 它应该存储在单独的逻辑层中 - 在单独的项目中,或者至少,在单独的 class 中。您可以使用存储库模式(它是一种模式吗?):
// Somewhere in a class library
public class Address
{
public string Name { get; set; }
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
}
public class AddressesRepository : IAddressesRepository
{
public Address[] ReadAll()
{
List<YourCustomClass> result = new List<YourCustomClass>();
var connection = SqlConnectionFactory.CreateAndOpenConnection();
var reader = new SqlCommand("select name, latitude, longitude from [<schema>].[<tablename>]", connection).ExecuteReader();
while (reader.Read())
{
result.Add(new Address {
Name = (string)reader["name"],
Latitude = (decimal)reader["latitude"],
Longitude = (decimal)reader["longitude"]
});
}
return result;
}
}
// Somewhere in ASP.NET WebAPI
private IAddressesRepository _addressesRepository = new AddressesRepository();
public IHttpActionResult GetHelloWorld()
{
var data = _addressesRepository.ReadAll();
return Ok(data);
}
我建议阅读一些关于分层架构和 ASP.NET WebAPI 本身的书籍,以便获得所有基本 ASP.NET 问题的答案。