2016-09-15 4 views
1

유효한 json으로 처리하려고하는 html 본문에 문자열이 있습니다. 내가받을 문자열은 유효한 json으로 문자열이 아닌 다음과 같은 스키마를 포함json 문자열의 필터 값이 잘못되었습니다.

äÄ 
    "key1": " 10", 
    "key2": "beigef}gtem Zahlschein", 
    "key3": "  G E L \ S C H T", 
    "key4": "M}nchen", 
    "key5": "M{rz", 
    "key6": "[huus" 
Ü 
ä 

내가 유효한 JSON 문자열을 만들 수있는 모든 잘못된 문자를 대체하는 기능을 작성했습니다,하지만 난 어떻게해야합니까 json에서 필요한 문자를 파괴하지 않고 역순으로? 내가 다른 사전에 액세스하려면 어떻게

deserializedRequest = JsonConvert.DeserializeObject<Dictionary<string, string>[]>(json); 

이 같은 사전에 그런

private static string FixChars(string input) 
    { 
     if (!string.IsNullOrEmpty(input)) 
     { 
      if (input.Contains("[")) 
      { 
       input = input.Replace("[", "Ä"); 
      } 
      if (input.Contains(@"\")) 
      { 
       input = input.Replace(@"\", "Ö"); 
      } 
      if (input.Contains("]")) 
      { 
       input = input.Replace("]", "Ü"); 
      } 
      if (input.Contains("{")) 
      { 
       input = input.Replace("{", "ä"); 
      } 
      if (input.Contains("|")) 
      { 
       input = input.Replace("|", "ö"); 
      } 
      if (input.Contains("}")) 
      { 
       input = input.Replace("}", "ü"); 
      } 
      if (input.Contains("~")) 
      { 
       input = input.Replace("~", "ß"); 
      } 
      //DS_Stern hat Probleme beim xml erstellen gemacht 
      //if (input.Contains("*")) 
      //{ 
      // input = input.Replace("*", "Stern"); 
      //} 
     } 
     return input; 
    } 

내가 JSON 배열을 직렬화하기 위해 시도했다 :

내가 문자를 대체하는 방법이다 값에 내 FixChars-method를 사용하고 유효 json 문자열을 다시 설정하십시오.

EDIT : IBM273을 통한 IBM273 및 디코딩은 유효한 json 문자열을 만들기에 적합하지만 여전히 사소한 오류가 있습니다. 문자 'ö'는 '|'입니다. 그 인코딩.

+0

같습니다 잘못된 [인코딩] (https://msdn.microsoft.com/en-us/library/ms404377(v=vs.110) .aspx)을 사용하십시오. 올바른 해결 방법은 올바른 인코딩을 사용하는 것입니다. 어떻게 문자열을 만들었습니까? – dbc

+0

오래된 cobol 기반 기계 – Zoba

+0

에서 제공 한 웹 사이트의 본문에서 문자열을 가져올 수 있습니다. 아마 관련이있을 수 있습니다. https://stackoverflow.com/questions/36336493/c-sharp-cannot-create-ebcdic-file-on -unisys-mainframe-windows-share – dbc

답변

3

그것은 사용자 JSON을 포함하는 HTML 페이지 것처럼 보인다하여 일으키는 기계중인 유니시스 A-시리즈 형 (cobol74)는 다른 인코딩을 사용하여 코드 복호 후 하나 encoding 및 사용에 바이트 스트림으로 인코딩 된 일부 문자는 다시 매핑되거나 손실됩니다. 문제를 해결하려면 해당 Unisys 컴퓨터에서 사용 된 원본 인코딩을 확인하고이를 사용하여 HTML 스트림을 디코딩해야합니다. 좀 더 복잡하게 만드는 이유는 .Net이 HTML을 디코딩하기 위해 어떤 인코딩을 사용했는지 확실하지 않기 때문입니다.

결정을 내리는 한 가지 방법은 예상 JSON의 샘플을 가져 와서 인코딩하고 .Net에서 사용할 수있는 인코딩 을 사용하여 코드를 디코딩하는 것입니다. 어떤 쌍의 인코딩이 잘못된 결과를 생성하는 경우 문자열을 인코딩하는 데 사용 된 인코딩이 Unisys 컴퓨터에서 사용 된 인코딩 일 수 있습니다. 그리고 변형을 뒤집어서 캐릭터가 삭제되지 않았다고 가정하고 문자열을 고칠 수 있습니다.

다음 코드는이 테스트를 수행합니다

var correctString = "{}[]"; 
var observedString = "äüÄÜ"; 

int count = 0; 
foreach (var toEncoding in Encoding.GetEncodings()) 
    foreach (var fromEncoding in Encoding.GetEncodings()) 
    { 
     var s = toEncoding.GetEncoding().GetString(fromEncoding.GetEncoding().GetBytes(correctString)); 
     if (s == observedString) 
     { 
      Console.WriteLine(string.Format("Match Found: Encoding via {0} and decoding via {1}", fromEncoding.Name, toEncoding.Name)); 
      count++; 
     } 
    } 
Console.WriteLine("Found {0} matches", count); 

인코딩 쌍의 무리를 포함하여 147 경기를 생산하고 있습니다. 전체 목록은 fiddle을 참조하십시오.

다음의 전체 JSON 문자열을 테스트하여 일치 줄이려고 시도하자 :

var correctJson = @"{[ 
    ""key1"": "" 10"", 
    ""key2"": ""beigefügtem Zahlschein"", 
    ""key3"": ""  G E L Ö S C H T"", 
    ""key4"": ""München"", 
    ""key5"": ""März"", 
    ""key6"": ""Ähuus"", 
    ""key7"": ""ö"", 
    ""key8"": ""ß"", 
] 
{"; 
var observedJson = @"äÄ 
    ""key1"": "" 10"", 
    ""key2"": ""beigef}gtem Zahlschein"", 
    ""key3"": ""  G E L \ S C H T"", 
    ""key4"": ""M}nchen"", 
    ""key5"": ""M{rz"", 
    ""key6"": ""[huus"", 
    ""key7"": ""|"", 
    ""key8"": ""~"", 
Ü 
ä"; 

int count = 0; 
foreach (var toEncoding in Encoding.GetEncodings()) 
    foreach (var fromEncoding in Encoding.GetEncodings()) 
    { 
     var s = toEncoding.GetEncoding().GetString(fromEncoding.GetEncoding().GetBytes(correctJson)); 
     if (s == observedJson) 
     { 
      Console.WriteLine(string.Format("Match Found: Encoding via {0} and decoding via {1}", fromEncoding.Name, toEncoding.Name)); 
      count++; 
     } 
    } 
Console.WriteLine("Found {0} matches", count); 

이 단지 2 EBCDIC을 생산하는 것은 일치 : 그래서

Match Found: Encoding via IBM01141 and decoding via IBM870 
Match Found: Encoding via IBM273 and decoding via IBM870 

이들 중 하나입니다 거의 확실 올바른 쌍의 인코딩. 하지만, 어느 쪽 이요? wikipedia에 따르면

CCSID 1141 is the Euro currency update of code page/CCSID 273. In that code page, the "¤" (currency) character at code point 9F is replaced with the "€" (Euro) character.

을 그래서 하나의 선택에 인코딩을 좁혀, 당신은 "€"문자로 샘플을 테스트해야합니다.

그런 다음 나는 다음과 같은 확장 메서드를 추가하는 경우 : 내가 수행하여 JSON을 해결할 수

public static class TextExtensions 
{ 
    public static string Reencode(this string s, Encoding toEncoding, Encoding fromEncoding) 
    { 
     return toEncoding.GetString(fromEncoding.GetBytes(s)); 
    } 
} 

을 : 당신이 증기에서 당신의`json` 문자열을 구성했을 수처럼

var fixedJson = observedJson.Reencode(Encoding.GetEncoding("IBM01141"), Encoding.GetEncoding("IBM870")); 
Console.WriteLine(fixedJson); 
+0

var json = Request.Body.AsString (Encoding.GetEncoding (20106)); 원하는대로 문자를 변경했지만 [,], {,}를 '?'로 반환합니다. – Zoba

+1

@Zoba - Request.Body.AsString (Encoding.GetEncoding ("ISO-8859-1"))'은 어떻습니까? 또한, 어떤 종류의 "오래된 cobol 기반 기계"이거 야? 어떤 종류의 IBM? – dbc

+0

그것은 [{대신 움라우트가 잘못되었으므로 'Ää'를 앞에 표시합니다. 내가 아는 한 Unisys A-Series 유형의 컴퓨터 (cobol74) – Zoba

관련 문제