【问题标题】:.NET 4.0 Web API Return JSON without escaping characters.NET 4.0 Web API 返回 JSON 而不转义字符
【发布时间】:2015-09-03 09:50:44
【问题描述】:

我已经阅读了无数的问题和答案,但还没有看到任何解决问题的方法。

我正在使用 newtonsoft JSON 库,只是想从表中返回一些 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);
    }

现在它按预期返回了我的结果集,但如果没有转义双引号,我根本无法让它返回,所以数据如下所示:

"[{\"name\":\"Aaron's Hill\",\"latitude\":51.18276,\"longitude\":-0.63503},{\"name\":\"Abbas Combe\",\"latitude\":51.00113,\"longitude\":-2.42178},

现在我阅读的许多答案都只是简单地说,因为您正在查看 IDE 中的结果。在我的情况下,这是不正确的,这是浏览器窗口中的输出(尝试了 IE 和 chrome),当你说给我显示 JSON 输出时,甚至 fiddler 抱怨它在位置 3 显示无效字符。

你会看到我已经注释掉了代码,这是我在这里找到的另一种返回 JSON 的方法,但它仍然会转义引号。不知道还能尝试什么?

【问题讨论】:

  • 您不应该返回序列化对象。您应该返回一个将由 ASP.NET 序列化的类对象。现在,你序列化一个序列化的对象——这就是你得到转义引号的原因。

标签: asp.net json json.net asp.net-web-api2


【解决方案1】:

你不应该自己序列化对象!
您应该返回一个将由 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
}

但是,返回 DataTable 对象听起来是错误的 - 它不会被正确序列化。
您需要像这样返回代表您的实体的自定义对象(仅作为示例,可能不起作用):

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 类中进行 SQL 查询。 SQL 连接和查询属于数据访问层 (DAL) - 它应该存储在单独的逻辑层 - 在单独的项目中,或者至少在单独的类中。您可以使用存储库模式(它是一种模式吗?):

// 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 问题的答案。

【讨论】:

  • 感谢 Yeldar 的全面回答!
猜你喜欢
  • 2011-02-14
  • 2018-04-28
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多