2016-09-15 4 views
1

Я получаю строку в html-модуле, которую я пытаюсь обработать в действительном json. Строка я получаю не является допустимой строка 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-строку из этого?

EDIT: IBM273 и декодирование через IBM037 прекрасно работает, чтобы создать допустимую строку json, но все еще содержит незначительную ошибку: символ 'ö' is '|' в этой кодировке.

+0

Похоже, вы можете построили свой 'json' строку из пар используя неверную [кодировку] (https://msdn.microsoft.com/en-us/library/ms404377 (v = vs.110) .aspx). Правильное исправление заключается в использовании правильного кодирования. Как вы создали строку? – dbc

+0

Я получаю строку из тела веб-сайта, предоставленного старой машиной на основе коболов – Zoba

+0

Возможно, возможно, связанный: https://stackoverflow.com/questions/36336493/c-sharp-cannot-create-ebcdic-file-on -unisys-mainframe-windows-share – dbc

ответ

3

Это выглядит так, как будто HTML-страницу, содержащую ваш JSON был закодирован в поток байтов от типа Unisys A-Series машины (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.

Таким образом, чтобы сузить кодировку одного выбора, вам необходимо протестировать образец с символом «€».

Затем, если добавить следующий метод расширения:

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 »))'? Кроме того, что такое «старая машина на основе кобола»? IBM какая-то? – dbc

+0

он возвращает 'Ää' спереди, а не [{и умлауты тоже ошибаются. Насколько я знаю что-то вроде машины типа Unisys A-Series (cobol74) – Zoba

 Смежные вопросы

  • Нет связанных вопросов^_^