【问题标题】:Return json in specific format Web API, Linq以特定格式返回 json Web API, Linq
【发布时间】:2018-07-27 12:11:28
【问题描述】:

我在创建 json 方面需要帮助。我有两个模型,即 QUESTIONBANK 和 QUESTIONOPTIONS。 QUESTIONOPTIONS 包含 QUESTIONBANK 中 Question 的多个选项

public partial class QUESTIONBANK
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public QUESTIONBANK()
        {
            this.QUESTIONOPTIONS = new HashSet<QUESTIONOPTION>();
        }

        public int QID { get; set; }
        public string QUESTION { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<QUESTIONOPTION> QUESTIONOPTIONS { get; set; }
    }

  public partial class QUESTIONOPTION
    {
        public int OPTIONID { get; set; }
        public Nullable<int> QID { get; set; }
        public string OPTIONTEXT { get; set; }
        public Nullable<bool> ISANSWER { get; set; }

        public virtual QUESTIONBANK QUESTIONBANK { get; set; }
    }

我在控制器中编写了如下代码

  public HttpResponseMessage GetQUESTIONBANKs()
        {
            var qSet = (from q in db.QUESTIONBANKs
                        join o in db.QUESTIONOPTIONS
                        on q.QID equals o.QID
                        select new questions
                        {
                            q = q.QUESTION,
                            a = o.ISANSWER.ToString(),
                            options = o.OPTIONTEXT
                        }).ToList();


            return Request.CreateResponse(HttpStatusCode.OK, qSet);
          }

我得到的json如下

[
  {
    "q": "Accounting provides information on",
    "a": "False",
    "options": "Cost and income for managers"
  },
  {
    "q": "Accounting provides information on",
    "a": "False",
    "options": " Companys tax liability for a particular year"
  },
  {
    "q": "Accounting provides information on",
    "a": "False",
    "options": "Financial conditions of an institution"
  },
  {
    "q": "Accounting provides information on",
    "a": "True",
    "options": " All of the above"
  },
  {
    "q": "The long term assets that have no physical existence but are rights that have value is known as",
    "a": "False",
    "options": "Current assets"
  },
  {
    "q": "The long term assets that have no physical existence but are rights that have value is known as",
    "a": "False",
    "options": "Fixed assets"
  },
  {
    "q": "The long term assets that have no physical existence but are rights that have value is known as",
    "a": "True",
    "options": "Intangible assets"
  },
  {
    "q": "The long term assets that have no physical existence but are rights that have value is known as",
    "a": "False",
    "options": "Investments"
  },
  {
    "q": "The assets that can be converted into cash within a short period (i.e. 1 year or less) are known as",
    "a": "True",
    "options": "Current assets"
  },
  {
    "q": "The assets that can be converted into cash within a short period (i.e. 1 year or less) are known as",
    "a": "False",
    "options": " Fixed assets"
  },
  {
    "q": "The assets that can be converted into cash within a short period (i.e. 1 year or less) are known as",
    "a": "False",
    "options": "Intangible assets"
  },
  {
    "q": "The assets that can be converted into cash within a short period (i.e. 1 year or less) are known as",
    "a": "False",
    "options": "Investments"
  },
  {
    "q": "Patents, Copyrights and Trademarks are",
    "a": "False",
    "options": " Current assets"
  },
  {
    "q": "Patents, Copyrights and Trademarks are",
    "a": "False",
    "options": " Fixed assets"
  },
  {
    "q": "Patents, Copyrights and Trademarks are",
    "a": "True",
    "options": "Intangible assets"
  },
  {
    "q": "Patents, Copyrights and Trademarks are",
    "a": "False",
    "options": "Investments"
  },
  {
    "q": "The following is not a type of liability",
    "a": "True",
    "options": "Short term"
  },
  {
    "q": "The following is not a type of liability",
    "a": "False",
    "options": "Current"
  },
  {
    "q": "The following is not a type of liability",
    "a": "False",
    "options": "Fixed"
  },
  {
    "q": "The following is not a type of liability",
    "a": "False",
    "options": "Contingent"
  }
]

而我需要以下格式的 json,其中问题选项需要以逗号分隔检索,并且 ISANSWER 标志为 true 的选项应位于“a”中。

quizData: {
        "questions": [{
            "q": "Look at the following selector: $(\"div\")<br/> What does it select?",
            "a": "All div elements",
            "options": [
                "All div elements",
                "The first div element",
                "All elements with the class \"div\""
            ]
        }, {
            "q": "Which of the following is correct",
            "a": "jQuery is a JavaScript Library",
            "options": [
                "jQuery is a JSON Library",
                "jQuery is a JavaScript Library"
            ]
        }, {
            "q": "jQuery uses CSS selectors to select elements?",
            "a": "True",
            "options": [
                "True",
                "False"
            ]
        }, {
            "q": "Which sign does jQuery use as a shortcut for jQuery?",
            "a": "the $ sign",
            "options": [
                "the % sign",
                "the $ sign",
                "the ? Sign"
            ]
        }, {
            "q": "Is jQuery a library for client scripting or server scripting?",
            "a": "Client scripting",
            "options": [
                "Client scripting",
                "Server scripting",
            ]
        }]
    }

非常感谢您的帮助。提前致谢

【问题讨论】:

  • 您是否尝试过使用自定义 Json 输出格式化程序?让您更好地控制如何呈现输出对象 => 您基本上可以转换为您想要的 json(或 xml/其他格式)
  • LINQ group by 子句可以实现
  • 从数据库中获取重复条目并在 C# 中按它们分组
  • 我不确定用实体框架做,但熟悉存储过程~

标签: c# linq entity-framework-6 asp.net-web-api2


【解决方案1】:

首先,这与 Web API、JSON 甚至 EntityFramwork 无关。

您有一个逻辑错误,该错误会在针对内存中集合的查询中以完全相同的方式表现出来,并且从未序列化。

输出完全符合预期。

但是更正很容易。

以下方法可以解决问题

public IEnumerable<QuestionViewModel> GetQUESTIONBANKs()
{
    return from question in db.QUESTIONBANKs
                join option in db.QUESTIONOPTIONS
                on question.ID equals option.QID
                into questonOptions
                select new QuestionViewModel
                {
                    Q = question.QUESTION,
                    A = questionOptions.First(o => o.ISANSWER).OPTIONTEXT,
                    Options = from o in questionOptions select o.OPTIONTEXT
                };
      }

请注意,这展示了 LINQ 最强大的方面之一 - 投影分层结果的能力。

但是,如果您的 EntityFramwork 和 Database 设置正确,您不需要自己编写连接

from question in db.QUESTIONBANKs
select new QuestionViewModel
{
    Q = question.QUESTION,
    A =questionOptions.First(o => o.ISANSWER).OPTIONTEXT,    
    Options = from o in questionOptions select o.OPTIONTEXT
}

【讨论】:

  • 不,我的意思是 A 应该包含正确答案选项,而不是正确或错误
【解决方案2】:

您可以从数据库中聚合结果并将其包装在匿名类型中

var aggr = qSet.GroupBy(x => x.q)
               .Select(t => new { 
                              q = t.Key, 
                              a = t.FirstOrDefault(ans => ans.a == "True").options, 
                              options = t.Select(ans => ans.options).ToList() });

var result = new { quizData = new { questions = aggr }};
return Request.CreateResponse(HttpStatusCode.OK, result);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    • 2017-03-10
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多