Странная проблема с потоками - PullRequest
1 голос
/ 28 июня 2010

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

Сначала я десериализую его в сущность, подобную этой:

XmlSerializer s = new XmlSerializer(typeof(TransactionResults));
TransactionResults t = (TransactionResults)s.Deserialize(stream);

Это, конечно, перемещает поток до конца, поэтому я не могу записать исходное значение.

Я пытался найти начало, чтобы затем прочитать его с StreamReader, но он выдает NotSupportedException

В качестве теста я попытался повторно сериализовать его (я создал все объекты снова, чтобы избежатьиспользовать их, чтобы увидеть, была ли это проблема)

private static string GetContents(TransactionResults t)
{
    XmlSerializer s = new XmlSerializer(typeof(TransactionResults));
    MemoryStream stream = new MemoryStream();
    s.Serialize(stream, t);
    return new StreamReader(stream).ReadToEnd();
}

Этот метод возвращает пустую строку.

(Очевидно, что если я инвертирую логику, значение будет записано в журнал, но затем яне могу получить объект)

Что я делаю не так?Как лучше всего десериализовать значение в объект и записать его в виде строки?

Ответы [ 3 ]

4 голосов
/ 28 июня 2010

Вы должны быть в состоянии найти начало MemoryStream без проблем:

private static string GetContents(TransactionResults t)
{
    XmlSerializer s = new XmlSerializer(typeof(TransactionResults));
    MemoryStream stream = new MemoryStream();
    s.Serialize(stream, t);
    stream.Position = 0; // Rewind to the beginning of the stream
    return new StreamReader(stream).ReadToEnd();
}

Если вы хотите зарегистрировать исходные данные вместо этого, вам фактически необходимо скопировать их вMemoryStream для начала - тогда вы можете перематывать его так часто, как захотите.

Я считаю полезным иметь такой метод для исчерпания одного потока и записи в другой:

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[8 * 1024];
    int len;
    while ( (len = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, len);
    }    
}

Вы можете назвать эту передачу входным потоком вашей службы в качестве ввода, а новый MemoryStream в качестве вывода.

0 голосов
/ 28 июня 2010

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

public static string ToXmlString(object xmlObject)
{
    if (xmlObject == null)
        throw new NullReferenceException("xmlObject cannot be null.");

    String xmlResult = null;

    XmlSerializer serializer = new XmlSerializer(xmlObject.GetType());
    using (StringWriter writer = new StringWriter())
    {
        serializer.Serialize(writer, xmlObject);
        xmlResult = writer.ToString();
    }

    return xmlResult;
}
0 голосов
/ 28 июня 2010

Считайте поток в поток памяти и работайте с ним, он поддерживает поиск.

...