【问题标题】:Tweak the controller in returning the JSON Object to a specific format调整控制器以将 JSON 对象返回为特定格式
【发布时间】:2018-12-04 09:40:27
【问题描述】:

任何人都知道我如何通过使用控制器以某种格式返回 JSON 对象,以便它以指定的顺序显示数据,如下所示。我曾尝试在线研究解决方案,发现他们中的大多数都使用控制器,但我对他们提供的解决方案感到困惑。

当前结果

{
    "Table:" [
        {
            "ED_Name": "Ang Mo Kio GRC",
            "GARO_Name": "Central CDC"
        },
        {
            "ED_Name": "Bishan-Toa Payoh GRC",
            "GARO_Name": "Central CDC"
        },
    ]
}

预期结果

{
    "Table": [
        {
            "Central CDC": ["Ang Mo Kio GRC"]
        },
        {
            "North-East CDC": ["Pasir Ris - Punggol GRC", "Tampines GRC"]
        }
    ]
}

控制器代码

public class GAROController : ApiController
{

    Database_Access_Data.db dblayer = new Database_Access_Data.db();

    [System.Web.Http.HttpGet]
    [System.Web.Http.Route("api/GARO/GetGAROList")]
    public DataSet CheckLockedOut()
    {
        DataSet ds = dblayer.GetGAROList();
        return ds;
    }
}

以及从数据库调用存储过程的代码:

public DataSet GetGAROList()
{
    SqlCommand com = new SqlCommand("GetCDC", con);
    com.CommandType = CommandType.StoredProcedure;
    SqlDataAdapter da = new SqlDataAdapter(com);
    DataSet ds = new DataSet();
    da.Fill(ds);

    return ds;
}

从数据库中检索数据的存储过程

  /****** Object:  StoredProcedure [dbo].[GetCDC]    Script Date: 4/12/2018 
  5:30:01 PM ******/
 SET ANSI_NULLS ON
 GO
 SET QUOTED_IDENTIFIER ON
 GO
 ALTER PROCEDURE [dbo].[GetCDC]
  AS 
  BEGIN 
  Select E.Name AS ED_Name, G.Name AS GARO_Name
  From ElectoralDivision E
  INNER JOIN GARO G ON G.ID = E.GAROID
  ORDER BY G.Name, E.Name
  END

【问题讨论】:

  • 这段代码有什么问题?是代码引起了您的困惑吗?如果是这样,是什么导致了这种混乱?
  • 这段代码的问题是它直接从数据库中的存储过程返回数据,如上面Current下所示。我想修改数据,使其在返回视图之前采用这种格式而不是原始格式,如 Intended 所示
  • 您的“当前结果”不一致且不可能正确:它以 [ 开头,以 } 结尾。
  • 此外,您的“预期结果”显示的数据似乎是从空中提取的。在您的示例中找不到["Sengkang West GRC", "def"] 中的任何值。没有更多细节,无法正确回答。
  • 对于当前结果,我在输入结果时出错并进行了编辑

标签: c# json asp.net-mvc


【解决方案1】:

您需要创建自定义 json 转换器,将每个属性转换为您的自定义格式。

public class CustomJsonConverter : JsonConverter
{
    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JArray jArray = new JArray();
        if (value != null)
        {
            foreach (var item in (Dictionary<string, List<string>>)value)
            {
                JObject jObject = new JObject();
                jObject.Add(new JProperty(item.Key, JArray.FromObject(item.Value)));
                jArray.Add(jObject);
            }
        }

        JObject jMainObject = new JObject();
        jMainObject.Add(new JProperty("Table", jArray));
        jMainObject.WriteTo(writer);
    }
}

你可以像上面那样使用转换器

//Your DataSet filled with stored procedure result.
DataSet ds = dblayer.GetGAROList();

//Populate DataTable from above DataSet
DataTable dt = ds.Tables[0];

//Project your data from DataTable to Dictionary
var result = (from row in dt.AsEnumerable()
              group row by row.Field<string>("GARO_Name") into grp
              select new
              {
                  GARO_Name = grp.Key,
                  ED_Name = grp.Select(x => x.Field<string>("ED_Name")).ToList()
              }).ToDictionary(x => x.GARO_Name, x => x.ED_Name);

//Use above Converter 
string json = JsonConvert.SerializeObject(result, new CustomJsonConverter());

//Print formatted json to console
Console.WriteLine(JObject.Parse(json));

输出:

【讨论】:

    猜你喜欢
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多