我目前正在对来自JIRA的webhook URL进行反序列化,但是我在将MVC应用程序中的控制器中的注释部分反序列化时遇到问题。
目前我在正确地反序列化所有内容,除了Json有效负载的注释部分。
这是JSON Payload中评论的内容:
'comments':[
{'id':'71980','displayName':'Ciaran','active':true},'created':'2015-06-10T09:30:07.983+0100','updated':'2015-06-10T09:30:07.983+0100'},
{'id':'72026','displayName':'Ciaran ','active':true},'created':'2015-06-10T14:50:34.253+0100','updated':'2015-06-10T14:50:34.253+0100'}]
使用Json2CSharp然后复制我需要的类,注释看起来像这样:
然后这些类看起来像这样:
Public Class Rootobject
Public Property expand As String
Public Property id As String
Public Property self As String
Public Property key As String
Public Property fields As Fields
End Class
Public Class Fields
Public Property comment As Comment
End Class
Public Class Comment
Public Property startAt As Integer
Public Property maxResults As Integer
Public Property total As Integer
Public Property comments As List(Of Comment2)
End Class
Public Class Comment2
Public Property body As String
Public Property created As Date
Public Property updated As Date
End Class
我不确定如何正确地反序列化我尝试这样做:
Dim reader As System.IO.StreamReader = New System.IO.StreamReader(HttpContext.Request.InputStream)
Dim rawSendGridJSON As String = reader.ReadToEnd()
Dim issue As Rootobject = JsonConvert.DeserializeObject(Of Rootobject)(rawSendGridJSON)
这适用于除评论之外的所有其他内容,我收到此错误消息:
无法将当前JSON数组(例如[1,2,3])反序列化为类型“class.Comment1”,因为该类型需要JSON对象(例如){“name”:“value”})才能正确反序列化。
我应该如何正确反序列化?
rootObject Json看起来像这样:
"expand":"renderedFields,names,schema,transitions,operations,editmeta,changelog,
"id": "41948",
"self": "http://jira:8080/rest/api/latest/issue/41948",
"key": "OP-155",
"fields": {
"comment": {
"startAt": 0,
"maxResults": 9,
"total": 9,
"comments": []
}
}
我可以从rootObject成功获取ID或密钥,但在“fields”部分获取注释会给我错误。但我可以从“字段”部分获取信息,例如我可以显示摘要或创建。
注释数量的问题,例如有九个,我反序列化的方式不正确处理。
尝试this link问题在于评论,其中包含已验证的json paylaod
答案 0 :(得分:2)
commentary link中提供的json与问题中的类不匹配。例如,您的RootObject
类与容器完全匹配,但主要是Issue
类除了" expand"属性:
{
"timestamp": 1437140952183,
"webhookEvent": "jira:issue_updated",
"user": {
...
,
"displayName": "Ciaran",
"active": true,
"timeZone": "Europe/London"
},
"issue": {...
},
"comment": {...
}...
基于jsfiddle json,根(可以重命名)应定义为:
Public Class CiaranObj
Public Property timestamp As Long
Public Property webhookEvent As String
Public Property user As Actor
Public Property issue As Issue
Public Property comment As CommentItem
End Class
重要说明:提供的jsfiddle样本可能已完成,也可能不完整。各种类中有许多未定义的类型。例如,Fields
有几个带有空值的类型导致:
Property customfield_10070 As Object
数据存在时, Object
可能不是最佳类型。同样,TimeTracking
完全未定义。
显然,除了评论之外,你什么都不感兴趣。如果为true,则可以解析json。如果你看一下像jsonlint.com这样的格式化的json,你可以看到这些关系。所以,只是得到评论:
Dim jstr = ' from whereever
' extract comments to reduce typing and typos
Dim comments = myJ("issue")("fields")("comment")
' get the comment count
Dim CommentCount = Convert.ToInt32(comments("maxResults"))
'print them
For n As Int32 = 0 To CommentCount - 1
Console.WriteLine("ID: {0}, Created: {1} upd Author: {2}",
comments("comments")(n)("id").ToString,
comments("comments")(n)("created").ToString,
comments("comments")(n)("author")("displayName").ToString)
Next
输出:
ID:72430,创建时间:2015/6/16 8:48:52更新作者:Ciaran ID:72431,创建时间:2015年6月16日上午9:02:16更新作者:Ciaran ID:72661,创建时间:2015年6月18日上午9:58:12更新作者:Ciaran
正如您在格式化的JsonLint显示中所注意到的那样,注释实际上比根更深。也许有一些类似于上面的其他处理,但没有提到。
要反序列化为对象,您需要使用类。您可以删除任何您不关心的属性,但无法将属性从一个类迁移到另一个类。使用任何机器人 - json2csharp,jsonutils.com 1 创建VB类甚至Visual Studio 2012或更高版本(Edit - Paste Special - Paste as Json Classes
- 来自动创建类,你可能想要花一点时间来规范"班级。
User
类一遍又一遍地重复User
,Assignee
,Creator
等。我将其缩减为一个名为Actor
的类型(类)。 AvatarUrls
也会一遍又一遍地重复AvatarUrls1
等。您只需要一种类型。Comment
Fields
类型
Comment
还包含一系列评论项,我将其重命名为CommentItem
CommentItem
也会在根对象中使用,但机器人会将其称为Comment2
这是您在第一个json片段中显示的内容comments
属性可以定义为数组或List<T>
,如图所示请注意,您可以移除任何您不关心的属性(但您无法移动或只是重命名它们)。我做了什么:
Public Class CiaranObj
Public Property timestamp As Long
Public Property webhookEvent As String
Public Property user As Actor
Public Property issue As Issue
Public Property comment As CommentItem
End Class
Public Class Actor
Public Property self As String
Public Property name As String
Public Property key As String
Public Property emailAddress As String
Public Property avatarUrls As Avatarurls
Public Property displayName As String
Public Property active As Boolean
Public Property timeZone As String
End Class
Public Class Avatarurls
' provide property mapping for illgal names
<JsonProperty("48x48")>
Public Property _48x48 As String
<JsonProperty("24x24")>
Public Property _24x24 As String
<JsonProperty("16x16")>
Public Property _16x16 As String
<JsonProperty("32x32")>
Public Property _32x32 As String
End Class
Public Class Issue
Public Property id As String
Public Property self As String
Public Property key As String
Public Property fields As Fields
End Class
Public Class Fields
'Public Property issuetype As Issuetype ' not shown
' ...
Public Property summary As String
Public Property creator As Actor
Public Property reporter As Actor
Public Property progress As Progress ' not shown
Public Property comment As Comment
End Class
Public Class Comment
Public Property startAt As Integer
Public Property maxResults As Integer
Public Property total As Integer
Public Property comments As CommentItem()
' or:
'Public Property comments As List(of CommentItem)
End Class
Public Class CommentItem
Public Property self As String
Public Property id As String
Public Property author As Actor
Public Property body As String
Public Property updateAuthor As Actor
Public Property created As DateTime
Public Property updated As DateTime
End Class
呼!现在,您可以反序列化为CiaranObj
对象:
Dim jstr = ...from whereever
Dim complexJ = JsonConvert.DeserializeObject(Of CiaranObj)(jstr)
' reduce typing
Dim c As Comment = complexJ.issue.fields.comment
For n As Int32 = 0 To c.maxResults - 1
Console.WriteLine("ID: {0}, Created: {1} upd Author: {2}",
c.comments(n).id.ToString,
c.comments(n).created.ToString,
c.comments(n).author.displayName)
Next
它打印相同的信息。
同样,这在评论中提供的jsfiddle上工作正常。它显然已被消毒,并且在此过程中,可能已经进行了其他改变(例如,缺失&#34;扩展&#34;)。
1 jsonutils.com非常酷,因为它可以创建VB类,但实际上它在这个json上运行不足:生成的类是不完整的。这显然是由于尺寸。
答案 1 :(得分:0)
自提供的&#34; JSON&#34; string无效,假设您无法对其进行任何操作,您可以使用String.Split(正则表达式)方法快速处理它并清除非转义控制字符,如[,{,&#39 ;,&#34;使用replace方法:String.Replace(&#34; [&#34;,&#34;&#34;)例如。
因此,您可以创建一个CommentInfo类,其中包含与注释相关的所有信息,并使该函数返回该类的已填充实例。