如何正确地反序列化JIRA webhook中的注释

时间:2015-06-10 14:27:51

标签: .net json asp.net-mvc vb.net jira

我目前正在对来自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

2 个答案:

答案 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类一遍又一遍地重复UserAssigneeCreator等。我将其缩减为一个名为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类,其中包含与注释相关的所有信息,并使该函数返回该类的已填充实例。