【问题标题】:C# MVC Return List in Formatted Json格式化 Json 中的 C# MVC 返回列表
【发布时间】:2020-10-28 11:06:39
【问题描述】:

有一个以 Json 形式返回的列表,但希望将其格式化如下。无法弄清楚为什么我似乎无法正确格式化它。

[{
    "AppFormName": "TFB Test Application",
    "Questions": [{
        "QuestionName": "How old are you?",
        "QuestionType": 1
    },
    {
        "QuestionName": "Where are you from?",
        "QuestionType": 1
    }]
},
{
    "AppFormName": "HLL",
    "Questions": [{
        "QuestionName": "How old are you?",
        "QuestionType": 1
    },
    {
        "QuestionName": "Where are you from?",
        "QuestionType": 1
    },
    {
        "QuestionName": "What Game are you applying for?",
        "QuestionType": 2
    },
    {
        "QuestionName": "Do you agree to the clan rules",
        "QuestionType": 3
    }]
}]

这是我的代码当前生成的:

[
    {
        "AppFormName": "TFB Test Application",
        "QuestionName": "How old are you?",
        "QuestionType": 1
    },
    {
        "AppFormName": "TFB Test Application",
        "QuestionName": "Where are you from?",
        "QuestionType": 1
    },
    {
        "AppFormName": "HLL",
        "QuestionName": "How old are you?",
        "QuestionType": 1
    },
    {
        "AppFormName": "HLL",
        "QuestionName": "Where are you from?",
        "QuestionType": 1
    },
    {
        "AppFormName": "HLL",
        "QuestionName": "What Game are you applying for?",
        "QuestionType": 2
    },
    {
        "AppFormName": "HLL",
        "QuestionName": "Do you agree to the clan rules",
        "QuestionType": 3
    }
]

这是我试图序列化结果的控制器;

public ActionResult AccessToken(string authorizationCode)
{
    UserFunctions.AccessToken(authorizationCode);
    var results = UserFunctions.userApplications;

    return Json(results , JsonRequestBehavior.AllowGet);
}

型号:

public class UserApplications
{
    public string AppFormName { get; set; }
    public string QuestionName { get; set; }
    public int QuestionType { get; set; }
}

获取数据的函数;

   public static List<Models.UserApplications> GetUserApplications(string ClientId)
    {
        userApplications.Clear();

        var getUserApplications = getUserApplicationsSQL;

        using (var conn = new MySqlConnection(dataConn))
        {
            using (var cmd = new MySqlCommand(getUserApplications, conn))
            {
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddWithValue("@DiscordClientID", ClientId);
                cmd.Connection.Open();
                using (var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                {
                    while (dr.Read())
                    {
                        var u = new Models.UserApplications
                        {
                            AppFormName = dr["AppFormName"].ToString(),
                            QuestionName = dr["QuestionName"].ToString(),
                            QuestionType = dr.GetInt32(dr.GetOrdinal("TypeID")),
                        };
                        userApplications.Add(u);
                    }
                }
            }
        }

        return userApplications;
    }

【问题讨论】:

  • Json() 已经将对象序列化为 json,也描述了如何格式化 json here,但您的格式似乎不是标准格式,所以除非您想自己编写格式化程序我建议WriteIndented
  • 您正在对数据进行双重序列化。请注意return Json(... 将自动序列化您提供的任何内容。因此,如果您为其提供预序列化的 JSON,它将尝试再次对其进行序列化,从而导致垃圾。只需将results 对象直接提供给该方法即可,无需手动涉及JsonSerializer。
  • @ADyson 最初是这样做的,但无法按照我要求的方式进行格式化,所以尝试了上面发布的方式。
  • 我明白了。正如我们所解释的那样,您尝试的方式不会改善任何事情。你所做的只是让相同的过程发生两次。请恢复您的第一次尝试。然后,请向我们展示生成的 JSON 究竟是什么。最后请向我们展示您想要的实际 JSON。您现在的预期结果示例真的不清楚,因为它不是有效的 JSON。最好向我们展示一个有效的样本,以便我们确切地知道您的意思。
  • 为了让大家更清楚,我将这些结构添加到主要问题中

标签: c# json asp.net-mvc ado.net


【解决方案1】:

您需要代码将现有数据结构转换为可生成所需 JSON 结构的数据结构。这可以使用 Linq 相对容易地完成。然后您需要在您的操作方法中返回该列表:

public ActionResult AccessToken(string authorizationCode)
{
    UserFunctions.AccessToken(authorizationCode);
    var results = UserFunctions.userApplications;

    var appFormList = results.GroupBy(s => s.AppFormName).Select(g => new
    {
      AppFormName = g.Key, Questions = g.Select(a => new
      {
        a.QuestionName, 
        a.QuestionType
      })
    });

    return Json(appFormList, JsonRequestBehavior.AllowGet);
}

现场演示:https://dotnetfiddle.net/sRIy72

(感谢 this post 使用 Linq 的想法。)

【讨论】:

    【解决方案2】:

    这可以简单地通过分组来实现:

    public ActionResult AccessToken(string authorizationCode)
    {
        UserFunctions.AccessToken(authorizationCode);
        List<UserApplications> results = UserFunctions.userApplications;
        var data = from p in results 
               group p by p.AppFormName into g
               select new { AppFormName = g.Key, Questions = g.Select(x=> new { QuestionName = x.QuestionName, QuestionType = x.QuestionType}).ToList() };
    
        return Json(data , JsonRequestBehavior.AllowGet);
    }
    

    【讨论】:

    • 很好的尝试,但它并不能完全产生正确的输出 - 与问题中的示例进行比较仔细检查。此外,除了 Linq 语法的不同风格之外,它与我已经发布的基本相同。
    • 是的,但你不需要额外的模型或方法,它可以用匿名类型处理,检查上面的函数它会产生问题中所述的确切结果。
    • 拥有一个额外的方法和一个强类型是很好的封装——它使代码可重用。这就是我这样做的原因。一般来说,这是一种很好的编程习惯。但我同意为了这个例子的目的可以缩短它。不过,您的新版本会正常工作,是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2012-07-09
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    相关资源
    最近更新 更多