在MVC4中使用WebApi,如何将动态json反序列化为具体类型?

时间:2014-07-29 16:31:55

标签: c# asp.net-mvc json asp.net-mvc-4 asp.net-web-api

我正在尝试使用MVC4 WebApi来构建rest / json服务。

在我的控制器中我有方法:

    public HttpResponseMessage Post(dynamic message)

这包含一个对象,它总是有两个字段,type和action。

动作是创建或取消。

我写了三个类,Message,CreateMessage和CancelMessage,Message是另外两个继承的基类。

在阅读dynamic上的模糊信息后,我认为我能够做到这一点:

    public void ProcessMessage(dynamic message)
    {
        switch ((string)message.action)
        {
            case "CREATE":
                ProcessCreateMessage(message);
                break;
            case "CANCEL":
                ProcessCancelMessage(message);
                break;
        }
    }

    private void ProcessCancelMessage(CancelMessage message)
    {
          //Cancell
    }

    private void ProcessCreateMessage(CreateMessage message)
    {
        //Create
    }

但我得到的消息是关于没有重载(隐式转换)或"无法转换类型' Newtonsoft.Json.Linq.JObject'到' CancelMessage'"

课程

public class Message
{
    public string type { get; set; }
    public string action { get; set; }
}

public class CancelMessage : Message
{
    public string ref { get; set; }
    public string message { get; set; }
}

Json:

{
    "type" : "type",
    "action" : "cancel",
    "ref" : "RefNo",
    "message" : "a message"
}

我没有到这里来的是什么?

3 个答案:

答案 0 :(得分:2)

您可以将JSON反序列化为c#对象,如

var cancelMessage = new JavaScriptSerializer().Deserialize<CancelMessage>(message);

我认为默认情况下你不能将字符串(JSON)强制转换为对象。

答案 1 :(得分:1)

请通过Arcrain的回答。

Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?)

我认为在你的情况下,它会帮助你从同一个网址链接。

You can use the C# dynamic type to make things easier. This technique also makes re-factoring simpler as it does not rely on magic-strings.

Json

The json string below is a simple response from an http api call and it defines two properties: Id and Name.

{"Id": 1, "Name": "biofractal"}

C#

Use JsonConvert.DeserializeObject<dynamic>() to deserialize this string into a dynamic type then simply access its properties in the usual way.

var results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

Note: The NuGet link for the NewtonSoft assembly is http://nuget.org/packages/newtonsoft.json

希望它能解决你的问题。

答案 2 :(得分:0)

这是另一种解决方案,使用Janty和Babinicz发布的信息

像我一样在MVC 4中使用ApiController,如果你将dynamic说明为单个传入参数。

(我正在关注微软初学者对MVC4中Web Api的指南)

当你尝试将dynamic投射到某个东西时,它应该神奇地起作用,但我收到了错误。

尝试编写自定义强制转换操作符,但不能对动态

执行此操作

但似乎dynamicobject非常相似,因为它知道底层类型是什么,而且该类型是Newtonsoft的JObject

而来自dynamic的转换只是进行正常转换,在运行时而不是设计时编译。

因此,通过向模型类添加隐式转换运算符:

public class Message
{
    public string type { get; set; }
    public string action { get; set; }
}

public class CancelMessage : Message
{
    public string ref { get; set; }
    public string message { get; set; }

    public static implicit operator CancelMessage(JObject message)
    {
        var output = JsonConvert.DeserializeObject<CancelMessage>(message.ToString());            
        return output;
    }
}

public void ProcessMessage(dynamic message)
{
    switch ((string)message.action)
    {
        case "CANCEL":
            ProcessCancelMessage(message);
            break;
    }
}

private void ProcessCancelMessage(CancelMessage message)
{
      //Cancel
}

这才有效。

当然,如果我只是传递这个dynamic的东西,我的代码只会在json中的字段名称符合预期的情况下工作,这也是有争议的。