2016-06-21 2 views
2

MarkLogic의 JSON 응답을 사용하여 C#의 모델에 바인딩했습니다. 관련 조각은 다음과 같습니다 :.NET의 배열 내부에 JSON 객체 바인딩

{ 
    "snippets":{ 
     "match":[ 
     { 
      "value":[ 
       "In (consolidated) enforcement actions for failure to answer subpoena, appeal from ", 
       { 
        "highlight":{ 
        "value":"judgement" 
        } 
       }, 
       " for defendants." 
      ] 
     } 
     ] 
    } 
} 

는 두 개의 문자열 및 다른 JSON 객체를 포함하고 있기 때문에 내가 데 문제는, 외부 "값"배열입니다. C#에서이 배열을 바인딩 할 수있는 방법이 있습니까? 나의 현재의 모델은 다음과 같이 :

[JsonProperty(PropertyName = "snippets")] 
public MarkLogicSnippetsModel Snippets { get; set; } 

public class MarkLogicSnippetsModel 
{ 
    [JsonProperty(PropertyName = "match")] 
    public IEnumerable<MarkLogicMatchModel> Matches { get; set; } 
} 

public class MarkLogicMatchModel 
{ 
    [JsonProperty(PropertyName = "value")] 
    public IEnumerable<string> Values { get; set; } 
} 

그러나 배열의 객체가있을 때 작동하지 않습니다 IEnumerable<string>를 사용하여.

+2

JSON이 유효하지 않습니다. –

+0

@PaulSwetz 반환 된 응답의 일부일 뿐이므로 복사했을 때 유효하지 않은 이유입니다. – OstrichGlue

답변

1

JSON 자체가 매우 끔찍합니다.이 코드 모델은 내가 사용하기에 가장 좋은 코드 모델이며 실제로 동적 데이터를 사용하여 값 데이터를 사용해야합니다. ..... 최상위 ' 가치 '는 실제로 깔끔하게 파싱 할 수 없다. JS 당신이 가질 수 있기 때문에 약자로는 3 개 항목이 배열이지만, 그 중 두 문자열 그 중 하나가 객체 '하이라이트'입니다

public class Match 
{ 
    public List<object> value { get; set; } 
} 

public class Snippets 
{ 
    public List<Match> match { get; set; } 
} 

public class RootObject 
{ 
    public Snippets snippets { get; set; } 
} 
+0

큰 것은 아니므로 응답을 깨끗한 것. 가능하지 않은 경우 동적 제안을 구현해 보겠습니다. – OstrichGlue

+0

웨이 값은 서로 다른 두 가지로 정의됩니다. 또한 매핑 클래스를 만들 때 문제가됩니다. 한 곳에서는 그냥 문자열이고 다른 한 곳에서는 객체입니다. –

+0

JSON은 혼합 콘텐츠를 표현하려고 시도하기 때문에 "매우 끔찍한"것이지만 JSON은이를 위해 설계되지 않았습니다. .NET 객체에 더 쉽게 바인딩 할 수 있도록 JSON 형식을 어떻게 보이게 될까요? 혼합 된 컨텐츠를 잘 처리하는 XML로 결과를 다시 가져 오는 것은 어떻습니까? 스 니펫을 하류로 어떻게 사용할 계획입니까? 예를 들어, 검색 결과 화면에서 HTML로? 그것들을 HTML로 변환하고 .NET 객체에 문자열 (HTML)을 저장하는 것이 합리적일까요? –

1

당신이 발송하고있는 JSON은 자바 스크립트 호환 다른 유형의 객체, 문자열, 숫자 등. C#을 강력하게 배열을 입력 한 때문에

그러나

당신이 문자열 배열이어야 보내 JSON에 value을 의미 IEnumerable<string>, 될 수있는 values 배열을 선언, 당신은 객체를 넣을 수 없습니다. 기본적으로하려는 것은 다음과 같습니다.

List<string> strings = new List<string>(); 
strings.Add("123"); 
strings.Add(new { foo: "foo" }); 

작동하지 않습니다.

가장 간단한 해결책은 JSON 레이아웃을 C#으로 유효하게 변경하는 것입니다. 이를 사용할 수 있습니다

"match": [{ 
    "value": { 
     "text": "In (consolidated) enforcement actions for failure to answer subpoena, appeal from {0} for defendants.", 
     "markup": [{ 
      "type": "highlight", 
      "value" : "judgement" 
     }] 

    } 
}] 

Markup

public class Markup 
{ 
    [JsonProperty(PropertyName = "type")] 
    public string Type { get; set; } 
    [JsonProperty(PropertyName = "value")] 
    public string Value {get; set; } 
} 

에 대한 클래스를 추가 다음 Value

public class Value 
{ 
    [JsonProperty(PropertyName = "text")] 
    public string Text{ get; set; } 
    [JsonProperty(PropertyName = "markup")] 
    public IEnumerable<Markup> Markup {get; set; } 
} 

또 다른 하나는 다음 변경 MarkLogicMatchModel

public class MarkLogicMatchModel 
{ 
    [JsonProperty(PropertyName = "value")] 
    public IEnumerable<Value> Values { get; set; } 
} 

나중에 String.Format을 사용하여 구문 분석 된 태그를 텍스트에 추가 할 수 있습니다. 입력 된 텍스트에 { 또는 }이없고, 물론 사용자가 제어하는 ​​구성 요소의 입력 텍스트 인 경우 작동합니다.

그래도 작동하지 않는다면, 다른 방법으로 제안한대로 dynamic을 사용해야합니다. 그에 대한 자세한 내용 here

+0

응답 해 주셔서 감사합니다. JSON을 변경할 수 있는지 다른 팀원과 이야기하고 있습니다. 그렇지 않다면 나는 역동적 인 방식을 살펴볼 것입니다. – OstrichGlue

2

JSON이 일부 전체 문자열에서 일치를 나타내는 것으로 간주됩니다.이 경우에는 "judgment"문자열이 In (consolidated) enforcement actions for failure to answer subpoena, appeal from judgement for defendants.과 일치해야합니다. 따라서 데이터 모델은 다음을 수행 할 수 있어야합니다. 전체 문자열을 재구성 할뿐만 아니라 일치하는 부분을 찾아냅니다.

public class RootObject 
{ 
    [JsonProperty(PropertyName = "snippets")] 
    public MarkLogicSnippetsModel Snippets { get; set; } 
} 

public class MarkLogicSnippetsModel 
{ 
    [JsonProperty(PropertyName = "match")] 
    public IEnumerable<MarkLogicMatchModel> Matches { get; set; } 
} 

public class MarkLogicMatchModel 
{ 
    [JsonProperty(PropertyName = "value")] 
    public List<MarkLogicMatchEntry> Values { get; set; } 
} 

public enum MatchType 
{ 
    Normal, 
    Highlight, 
} 

[JsonConverter(typeof(MarkLogicMatchEntryConverter))] 
public class MarkLogicMatchEntry 
{ 
    public MatchType MatchType { get; set; } 

    public string Value { get; set; } 
} 

다음 변환기를 사용 :

class MarkLogicMatchEntryConverter : JsonConverter 
{ 
    JsonSerializer GetEnumSerializer() 
    { 
     return JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new[] { new StringEnumConverter { CamelCaseText = true } } }); 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(MarkLogicMatchEntry); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.Null) 
      return null; 
     else if (reader.TokenType == JsonToken.String) 
     { 
      return new MarkLogicMatchEntry { MatchType = MatchType.Normal, Value = reader.Value.ToString() }; 
     } 
     else 
     { 
      var obj = JObject.Load(reader); 
      var property = obj.Properties().FirstOrDefault(); 
      var type = ((JValue)property.Name).ToObject<MatchType>(GetEnumSerializer()); 
      var value = (string)property.Value.SelectToken("value"); 

      return new MarkLogicMatchEntry { MatchType = type, Value = value }; 
     } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var match = (MarkLogicMatchEntry)value; 
     if (match.MatchType == MatchType.Normal) 
     { 
      writer.WriteValue(match.Value); 
     } 
     else 
     { 
      var propertyName = (string)JToken.FromObject(match.MatchType, GetEnumSerializer()); 
      var obj = new JObject(new JProperty(propertyName, new JObject(new JProperty("value", match.Value)))); 
      obj.WriteTo(writer); 
     } 
    } 
} 
다음

검색된 문자열의 각 부분을 표현되는 JSON 변경할 수 없습니다 가정

, 나는 다음을 같은 데이터 모델을 건의 할 것 MarkLogicMatchEntry 클래스로 일치하지 않는 정상적인 부분 문자열은 MatchType = MatchType.Normal으로 표시됩니다. 일치하는 부분 문자열은 MatchType = MatchType.Highlight으로 표시됩니다. 이론적으로 이론적으로 다른 일치 유형 (예 : MatchType.Underline)을 추가 할 수 있습니다.