2016-09-15 38 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中需要的字母?

這是我如何替換字符:

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的陣列到解釋是這樣的:

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

如何訪問不同的字典,在值上使用我的FixChars方法並從中重新序列化一個有效的json字符串?

編輯:IBM273和解碼通過IBM037工作正常,創建一個有效的json字符串,但仍包含一個小錯誤:字符'ö'是'|'在那編碼。

+0

看起來你可能已經從蒸汽構建了你的'json'串使用錯誤的[編碼](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頁面被編碼成字節流在您Unisys的A系列類型的機器使用一個encoding,然後使用不同的編碼由代碼解碼,(cobol74)從而導致一些字符被重映射或丟失。要解決您的問題,您需要確定在該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.

因此,要縮小編碼到一個選擇,你需要測試的樣本與「€」字符。

然後,如果我添加下面的擴展方法:

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系列機器(cobol74) – Zoba