Вопрос

У меня есть следующий анализ XML в моем приложении:

    public static XElement Parse(string xml, string xsdFilename)
    {
        var readerSettings = new XmlReaderSettings
        {
            ValidationType = ValidationType.Schema,
            Schemas = new XmlSchemaSet()
        };
        readerSettings.Schemas.Add(null, xsdFilename);
        readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        readerSettings.ValidationEventHandler +=
            (o, e) => { throw new Exception("The provided XML does not validate against the request's schema."); };

        var readerContext = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.UTF8);

        return XElement.Load(XmlReader.Create(new StringReader(xml), readerSettings, readerContext));
    }

Я использую его для разбора строк, отправляемых в мою службу WCF в документы XML, для пользовательской дезерриализации.

Он работает нормально, когда я читаю в файлах и отправляю их через провод (запрос); Я проверил, что спецификация не отправляется напротив. В моем запросе обработчик я сериализацию объекта ответа и отправляя его обратно в виде строки. Процесс сериализации добавляет BOM UTF-8 на переднюю часть строки, что приводит к тому же коду, чтобы сломаться при расстановке ответа.

System.Xml.XmlException : Data at the root level is invalid. Line 1, position 1.

В исследовании я проделал в течение последнего часа или около того, кажется, что XmlReader должен почтить отс. Если я вручную снимаю спереди спереди строки, ответа XML разбирается нормально.

Я упускаю что-то очевидное или хотя бы что-то коварное?

РЕДАКТИРОВАТЬ: Вот код сериализации, который я использую для возврата ответа:

private static string SerializeResponse(Response response)
{
    var output = new MemoryStream();
    var writer = XmlWriter.Create(output);
    new XmlSerializer(typeof(Response)).Serialize(writer, response);
    var bytes = output.ToArray();
    var responseXml = Encoding.UTF8.GetString(bytes);
    return responseXml;
}

Если это просто вопрос XML, неверно, содержащий спектр, то я переключусь на

var responseXml = new UTF8Encoding(false).GetString(bytes);

Но вообще не было ясно от моих исследований, что СБ был незаконным в реальном этапе XML; увидеть, например, C # Обнаружение XML кодирования из байтового массива?

Это было полезно?

Решение

Строка XML не должна (!) Содержать BOM, BOM разрешен только в байтовых данных (например, потоках), которые кодируются с UTF-8. Это связано с тем, что строковое представление не кодируется, но уже последовательность символов Unicode.

Поэтому кажется, что вы загружаете неправильную строку, которая находится в коде, которую вы, к сожалению, не предоставили.

Редактировать:

Спасибо за размещение кода сериализации.

Вы не должны писать данные в MemoryStream, а скорее в StringWriter, который вы можете преобразовать в строку с TOSTRING. Поскольку это избегает прохождения через представление байта, это не только быстрее, но и позволяет избежать таких проблем.

Что-то вроде этого:

private static string SerializeResponse(Response response)
{
    var output = new StringWriter();
    var writer = XmlWriter.Create(output);
    new XmlSerializer(typeof(Response)).Serialize(writer, response);
    return output.ToString();
}

Другие советы

В моем запросе обработчик я сериализацию объекта ответа и отправляя его обратно в виде строки. Процесс сериализации добавляет BOM UTF-8 на переднюю часть строки, что приводит к тому же коду, чтобы сломаться при расстановке ответа.

Таким образом, вы хотите предотвратить добавление СБ в рамках процесса вашего сериализации. К сожалению, вы не предоставляете, какова ваша логика сериализации.

Что вы должны сделать, это обеспечить Utf8encoding. экземпляр создан через UTF8ENCODING (BOOL) Конструктор для отключения генерации СБ, и пропустите это Encoding Экземпляр к тому, что методы, которые вы используете, которые генерируют вашу промежуточную строку.

Стук не должен быть в строке в первую очередь.
Boms используются для обнаружения кодирования необработанного байтового массива; У них нет бизнеса в реальной строке.

От чего приходит строка?
Вы, вероятно, читаете это с неправильным кодированием.

Строки в C # кодируются как UTF-16, поэтому BOM будет неправ. Как правило, всегда кодируйте XML для байтовых массивов и декодируйте его из байтовых массивов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top