【问题标题】:Parsing Json .Net Web Api解析 Json .Net Web Api
【发布时间】:2016-05-25 20:53:05
【问题描述】:

我是 Web API 2 / Entity Framework 6 项目的新手,我正在制作 REST 服务,但对于一项特定服务,我将在对任何实体进行任何 CRUD 操作之前(通过 Post)接收 JSON模型,(必须对数据进行一些业务验证,添加或补充一些东西并决定要保存的实体),JSON 是:

{
    "head": {
        "action": "create",
        "object": "oneobject",
        "user": "theuser"
    },
    "object": {
        "name1": "a name 1",
        "name2": "a name 2",
        "description": "a description here"
    },
    "rule": [{
        "name": "any name",
        "value": "any value"
    }, {
        "name": "another name",
        "value": "another value"
    }]
}

所以 json 不直接映射到实体,实际上我没有模型或对象。使用它的更好方法是什么?我的意思是如何接收和解析json。我是 web api 和 rest 服务的新手,我希望你能帮助我并详细解释我。谢谢大家。

编辑:

  1. 任何与这种 json 匹配的 POCO 或类的想法。 (“规则”列表是变量,可以是一个或多个)。

  2. 创建此 poco 或类后,我是否必须基于此制作控制器?

【问题讨论】:

  • 最好的选择是创建模型来描述特定服务的作用。 JSON 本身没有架构(数据描述),建议这样做。
  • @doctor 没找到你。
  • 他建议你使用dynamic C# language feature
  • 他指的是expando对象...

标签: c# json entity-framework rest asp.net-web-api2


【解决方案1】:

正如其他人所说,您需要的是一个 POCO 对象来表示您的请求。根据您提供的信息,以下内容应该足够接近您所追求的:

public enum CrudAction
{
    Create,
    Read,
    Update,
    Delete
}

public sealed class CrudRequestHeader
{
    public CrudAction Action { get; set; }

    public string Object { get; set; }

    public string User { get; set; }
}

public sealed class RuleDefinition
{
    public string Name { get; set; }

    public string Value { get; set; }
}

public sealed class CrudRequest
{
    public CrudRequestHeader Head { get; set;}

    public Dictionary<string, string> Object { get; set; }

    public List<RuleDefinition> Rule { get; set; }
}

然后,在您的 Web API 控制器方法中,您可以采用 CrudRequest 类型的参数,您的 JSON 将被反序列化为此对象,例如:

public IHttpActionResult Post(CrudRequest crudRequest)
{
    // TODO Implementation
}

您可能注意到我使用Dictionary&lt;string, string&gt; 代替CrudRequest.Object,因为我们将提供多少个键/值是可变的,我假设所有值都是字符串,您可以使用object 值如果您愿意,但您将需要处理值的类型。同样的原则,我使用List&lt;RuleDefinition&gt; 代替CrudRequest.Rule 来满足可能提供的可变数量的规则。

可以在此处找到包含上述定义并与您的输入一起使用的 LINQPad 示例:http://share.linqpad.net/7rvmhh.linq

【讨论】:

  • 感谢@Lukazoid 的帮助和时间。效果很好。
  • 这是唯一对我有用的方法,经过数小时的尝试......不确定是不是因为我搬到了 CORE,但这很艰难
【解决方案2】:

虽然 JSON 可能不代表您模型中的逻辑实体,但您显然对 JSON 数据的“形状”有一个心智模型 - 我这么说是因为您在代码 sn-p 中定义了它。您应该创建一个 POCO(普通的旧 C# 对象)来表示此模型,并将传入的 JSON 请求反序列化为该类型的对象。将其反序列化为对象后,使用对象属性等处理此数据将很简单。

【讨论】:

  • 这个 JSON 的 POCO 怎么可能?因为它有三个对象(头、对象、规则),而“规则”对象可以是一个变量列表。
  • 抱歉,刚刚看到您的评论。看起来下面有一些很好的回应。
  • 感谢@Dan Forbes 的帮助和时间。
【解决方案3】:

最好的办法是创建一个类来模拟您期望返回的对象。

这样,在您的 Web API 方法中,您可以使用 [FromBody] 属性来自动解析请求的正文。

例子-

您的数据合同如下所示:

public class MyContract
{
  public string MyData { get; set;} 
}

在你的 ApiController 中

[HttpPost]
[Route("api/myobject")]
public async Task ReceiveMyObject([FromBody]MyContract object) {

  var data = object.MyData;
  // Do whatever you need to do here.
}

这可能看起来很乏味,但这会让您的代码保持井井有条。

编辑 因此,要以此创建合同:

{
    "head": {
        "action": "create",
        "object": "oneobject",
        "user": "theuser"
   },
    "object": {
        "name1": "a name 1",
        "name2": "a name 2",
        "description": "a description here"
    },
    "rule": [{
        "name": "any name",
        "value": "any value"
    }, {
        "name": "another name",
        "value": "another value"
    }]
} 

你会这样做:

public class MyContract 
{
    [JsonProperty("head")]
    public MetaObject Head 
    {
        get; set;
    }

    // Not sure if this will work, but it probably will
    [JsonProperty("object")]
    public JObject ExtendedInformation
    {
        get;
        set;
    }

    [JsonProperty("rule")]
    public Rule[] Rules 
    {
        get;
        set;
    }
}

// "MetaObject" definition omitted but you can understand my point with the below

public class Rule
{
    [JsonProperty("name")]
    public string Name
    {
        get;
        set;
    }

    [JsonProperty("value")]
    public string Value
    {
        get;
        set;
    }
}

【讨论】:

  • 怎么可能是这个 JSON 建模的类?因为它有三个对象(头、对象、规则),而“规则”对象可以是一个变量列表。
  • 在您的具体情况下,您可以创建一个类来表示每个属性。我会更新我的答案以反映这一点。
  • 感谢@Julius 的帮助和时间。
【解决方案4】:

通常 REST 服务会发布一个合约,这意味着某种元数据来描述其消息的内容,否则您不能将其称为 RESTful Web API。如果您想更好地了解什么是 REST,什么不是,请查看创建 REST API 术语的 Roy Fielding 的this post

因此,如果您的服务是真正的 REST 服务,您应该能够在某处进行描述,以便您可以解析媒体。

但是,如果您仍然找不到任何方法来理解 JSON 应该如何被解释,那么您可以在 C# 类中使用它:查看 Newtonsoft.Json 中的 JObject 类,它可以使用运行时的动态对象。

基本上是这样使用的:

using Newtonsoft.Json.Linq; // This needs the Newtonsoft.Json package

dynamic entity = JObject.Parse(jsonString);

string value = entity.key1;
string value2 = entity["key2"];

我用你的数据做了这个简单的demo

您还可以在 Newtonsoft 网站上查看该课程的完整文档。

【讨论】:

  • 感谢@Vyrira 的帮助和时间。
猜你喜欢
  • 2022-01-08
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2017-01-19
  • 2015-07-11
  • 2014-09-10
相关资源
最近更新 更多