Экспортируйте данные в файл ViewModel в XML-файл (WPF) [дубликат]

Чтобы понять, что mod_rewrite вам сначала нужно понять, как работает веб-сервер. Веб-сервер отвечает на HTTP-запросы . HTTP-запрос на самом базовом уровне выглядит следующим образом:

GET /foo/bar.html HTTP/1.1

Это простой запрос браузера на веб-сервер с запросом URL /foo/bar.html. Важно подчеркнуть, что он не запрашивает файл , он запрашивает только некоторые произвольные URL-адреса. Запрос также может выглядеть так:

GET /foo/bar?baz=42 HTTP/1.1

Это так же верно, как и запрос на URL-адрес, и он явно не имеет ничего общего с файлами.

Веб-сервер это приложение, прослушивающее порт, прием HTTP-запросов, поступающих на этот порт, и возвращение ответа. Веб-сервер полностью может отвечать на любой запрос любым способом, который он считает нужным / каким-либо образом вы настроили его для ответа. Этот ответ не является файлом, это HTTP-ответ , который может или не может иметь ничего общего с физическими файлами на любом диске. Веб-сервер не обязательно должен быть Apache, есть много других веб-серверов, которые являются всего лишь программами, которые работают постоянно и привязаны к порту, который отвечает на HTTP-запросы. Вы можете написать его самостоятельно. Этот параграф был предназначен для развода с любым понятием, что URL-адреса напрямую равны файлам, что действительно важно для понимания. :)

Конфигурация по умолчанию для большинства веб-серверов - это поиск файла, который соответствует URL-адресу на жестком диске. Если document root сервера установлен, скажем, /var/www, он может посмотреть, существует ли файл /var/www/foo/bar.html и обслуживать его, если это так. Если файл заканчивается на «.php», он вызовет интерпретатор PHP и , после чего вернет результат. Вся эта ассоциация полностью настраивается; файл не должен заканчиваться на «.php» для веб-сервера для запуска его через интерпретатор PHP, и URL-адрес не должен соответствовать конкретному файлу на диске, чтобы что-то произошло.

mod_rewrite - это способ переписать внутреннюю обработку запросов. Когда веб-сервер получает запрос на URL /foo/bar, вы можете переписать этот URL-адрес на что-то еще, прежде чем веб-сервер будет искать файл на диске в соответствии с ним. Простой пример:

RewriteEngine On
RewriteRule   /foo/bar /foo/baz

Это правило говорит всякий раз, когда запрос соответствует «/ foo / bar», перепишите его на «/foo/baz". Затем запрос будет обработан как если бы /foo/baz был запрошен. Это может быть использовано для различных эффектов, например:

RewriteRule (.*) $1.html

Это правило соответствует чему-либо (.*), а захватывает it ((..)), а затем перезаписывает его добавьте «.html». Другими словами, если /foo/bar был запрошенным URL-адресом, он будет обрабатываться так, как будто запрошено /foo/bar.html. См. http://regular-expressions.info для получения дополнительной информации о сопоставлении регулярных выражений, захвате и замене.

Другое часто встречающееся правило:

RewriteRule (.*) index.php?url=$1

Это опять-таки сопоставляет что-либо и переписывает его в файл index.php с первоначально запрошенным URL-адресом, добавленным в параметр запроса url. Т.е. для любых входящих и входящих запросов файл index.php выполняется, и этот файл будет иметь доступ к исходному запросу в $_GET['url'], поэтому он может делать с ним что угодно.

В первую очередь вы помещаете эти правила перезаписи в свой конфигурационный файл веб-сервера .

* Если разрешено первичным Apache, то вы можете поместить их в файл с именем .htaccess в корне вашего документа (т. Е. Рядом с вашими файлами .php). Файл конфигурации; это необязательно, но часто разрешено.

Что mod_rewrite делает not do

mod_rewrite не волшебным образом делает все ваши URL «хорошенькими». Это распространенное недоразумение. Если у вас есть эта ссылка на вашем веб-сайте:


нет ничего, что мог бы сделать mod_rewrite, чтобы сделать это красиво. Чтобы сделать это красивой ссылкой, вы должны:

  1. Измените ссылку на красивую ссылку:
    
    
  2. Используйте mod_rewrite на сервере для обработки запроса к URL /my/pretty/link, используя любой из описанных выше методов.

(Можно использовать mod_substitute для преобразования исходящих HTML-страниц

Существует много возможностей mod_rewrite и очень сложные правила соответствия, которые вы можете создать, включая цепочку нескольких переписываний, проксирование запросов на совершенно другую услугу или машину, возврат определенных кодов статуса HTTP в виде ответов, перенаправление запросов и т. д. Это очень мощный и может быть использован для хорошего использования, если вы понимаете основной механизм запроса HTTP-ответа. Он не автоматически делает ваши ссылки симпатичными.

См. Официальную документацию для всех возможных флагов и опций.

220
задан Peter Mortensen 13 May 2015 в 21:33
поделиться

11 ответов

Вы должны использовать XmlSerializer для сериализации XML. Ниже приведен пример фрагмента.

 XmlSerializer xsSubmit = new XmlSerializer(typeof(MyObject));
 var subReq = new MyObject();
 var xml = "";

 using(var sww = new StringWriter())
 {
     using(XmlWriter writer = XmlWriter.Create(sww))
     {
         xsSubmit.Serialize(writer, subReq);
         xml = sww.ToString(); // Your XML
     }
 }
381
ответ дан Matas Vaitkevicius 21 August 2018 в 08:11
поделиться
  • 1
    Кажется, отлично работает без линии XmlWriter writer = XmlWriter.Create(sww); – Paul Hunt 27 June 2014 в 11:52
  • 2
    using люди используют using s! Утилизируйте эти объекты! – Liam 11 September 2014 в 17:25
  • 3
    Чтобы иметь формат сериализованного объекта: XmlTextWriter writer = new XmlTextWriter(sww) { Formatting = Formatting.Indented }; вместо XmlWriter writer = XmlWriter.Create(sww); – Tono Nam 21 June 2015 в 15:22
  • 4
    Поскольку XmlWriter инкапсулирует StringWriter, вам не нужно распоряжаться обоими (первое использование избыточно), правильно? Я предполагаю, что XmlWriter позаботится об утилизации ... – talles 10 November 2015 в 21:46
  • 5
    @talles XmlWriter не инкапсулирует StringWriter, он использует ваш переданный StringWriter и не имеет ожиданий / ответственности его распоряжаться. Кроме того, StringWriter находится вне области XmlWriter, вы все еще можете захотеть его, когда XmlWriter будет удален, было бы плохое поведение для XmlWriter для размещения вашего StringWriter. Как правило, если вы заявляете то, что вам нужно, вы несете ответственность за его удаление. И неявное этому правилу, все, что вы не заявляете, вы не должны распоряжаться. Поэтому необходимы обе using s. – Arkaine55 24 May 2017 в 15:21

Вот хороший учебник о том, как это сделать

Для этого вам следует использовать класс System.Xml.Serialization.XmlSerializer.

3
ответ дан Aamir 21 August 2018 в 08:11
поделиться

Класс расширения:

using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace MyProj.Extensions
{
    public static class XmlExtension
    {
        public static string Serialize<T>(this T value)
        {
            if (value == null) return string.Empty;

            var xmlSerializer = new XmlSerializer(typeof(T));

            using (var stringWriter = new StringWriter())
            {
                using (var xmlWriter = XmlWriter.Create(stringWriter,new XmlWriterSettings{Indent = true}))
                {
                    xmlSerializer.Serialize(xmlWriter, value);
                    return stringWriter.ToString();
                }    
            }
        }
    }
}

Использование:

Foo foo = new Foo{MyProperty="I have been serialized"};

string xml = foo.Serialize();

Просто укажите пространство имен, содержащее ваш метод расширения в файле, в котором вы хотели бы использовать его, и это будет (в моем примере это будет: using MyProj.Extensions;)

Обратите внимание, что если вы хотите сделать метод расширения конкретным только для определенного класса (например, Foo), вы можете заменить T в методе расширения, например.

public static string Serialize(this Foo value){...}

25
ответ дан Aleksandr Albert 21 August 2018 в 08:11
поделиться
  • 1
    Я пробовал этот код, поскольку он кажется самым чистым, но в последней строке он не предлагает «Сериализовать ()». метод. Что мне не хватает? – ditto1977 26 December 2014 в 16:29
  • 2
    @ user312305 Мои искренние извинения, я отправил неправильную версию. Пожалуйста, см. Мой отредактированный ответ, нет необходимости в наследовании, он применим ко всем объектам! – Aleksandr Albert 26 December 2014 в 17:29
  • 3
    Очень приятно, мой друг! Теперь я просто использую XmlExtension.Serialize(foo);, и все хорошо! Большое спасибо. – ditto1977 26 December 2014 в 18:16
  • 4
    Здравствуйте, на самом деле вы можете просто вызвать foo.Serialize (), теперь все ваши объекты имеют метод Serialize (), когда вы ссылаетесь на пространство имен расширений :) – Aleksandr Albert 26 December 2014 в 23:34
  • 5
    Это работает правильно для меня, – Younes 2 March 2015 в 09:32

Вот базовый код, который поможет сериализовать объекты C # в xml:

using System;

public class clsPerson
{
  public  string FirstName;
  public  string MI;
  public  string LastName;
}

class class1
{ 
   static void Main(string[] args)
   {
      clsPerson p=new clsPerson();
      p.FirstName = "Jeff";
      p.MI = "A";
      p.LastName = "Price";
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
      x.Serialize(Console.Out, p);
      Console.WriteLine();
      Console.ReadLine();
   }
}    
-1
ответ дан Ali Asad 21 August 2018 в 08:11
поделиться

Или вы можете добавить этот метод к своему объекту:

    public void Save(string filename)
    {
        var ser = new XmlSerializer(this.GetType());
        using (var stream = new FileStream(filename, FileMode.Create))
            ser.Serialize(stream, this);
    }
0
ответ дан Bigjim 21 August 2018 в 08:11
поделиться

Это немного сложнее, чем вызов метода ToString для класса, но не много.

Вот простая функция выписки, которую вы можете использовать для сериализации любого типа объекта. Он возвращает строку, содержащую сериализованный XML-контент:

public string SerializeObject(object obj)
{
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
    using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) {
        serializer.Serialize(ms, obj);
        ms.Position = 0;
        xmlDoc.Load(ms);
        return xmlDoc.InnerXml;
    }
}
6
ответ дан Cody Gray 21 August 2018 в 08:11
поделиться
    string FilePath = ConfigurationReader.FileLocation;   //Getting path value from web.config            
    XmlSerializer serializer = new XmlSerializer(typeof(Devices)); //typeof(object)
            MemoryStream memStream = new MemoryStream();
            serializer.Serialize(memStream, lstDevices);//lstdevices : I take result as a list.
            FileStream file = new FileStream(folderName + "\\Data.xml", FileMode.Create, FileAccess.ReadWrite); //foldername:Specify the path to store the xml file
            memStream.WriteTo(file);
            file.Close();

Вы можете создать и сохранить результат в виде XML-файла в нужном месте.

1
ответ дан Dev Try 21 August 2018 в 08:11
поделиться

мой рабочий код. Возвращает utf8 xml разрешает пустое пространство имен.

// override StringWriter
public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => Encoding.UTF8;
}

private string GenerateXmlResponse(Object obj)
{    
    Type t = obj.GetType();

    var xml = "";

    using (StringWriter sww = new Utf8StringWriter())
    {
        using (XmlWriter writer = XmlWriter.Create(sww))
        {
            var ns = new XmlSerializerNamespaces();
            // add empty namespace
            ns.Add("", "");
            XmlSerializer xsSubmit = new XmlSerializer(t);
            xsSubmit.Serialize(writer, obj, ns);
            xml = sww.ToString(); // Your XML
        }
    }
    return xml;
}

Пример возвращает ответ Yandex api payment Aviso url:

<?xml version="1.0" encoding="utf-8"?><paymentAvisoResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" performedDatetime="2017-09-01T16:22:08.9747654+07:00" code="0" shopId="54321" invoiceId="12345" orderSumAmount="10643" />
1
ответ дан dev-siberia 21 August 2018 в 08:11
поделиться

Чтобы сериализовать объект, выполните:

 using (StreamWriter myWriter = new StreamWriter(path, false))
 {
     XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
     mySerializer.Serialize(myWriter, objectToSerialize);
 }

Также помните, что для работы XmlSerializer нужен конструктор без параметров.

85
ответ дан Peter Mortensen 21 August 2018 в 08:11
поделиться
  • 1
    очень приятное решение, мне нравится, как вы реализовали это как метод расширения – Spyros 30 August 2013 в 12:38
  • 2
    Одна вещь, которую я предлагаю здесь: удалить блок try ... catch. Это не дает вам никакой пользы и просто искажает ошибку, которая бросается. – jammycakes 20 October 2014 в 11:50
  • 3
    writer.Flush() является избыточным в блоке using - метод writer Dispose() будет очищать его для вас. – bavaza 13 March 2015 в 11:38
  • 4
    Мой опыт показал, что это неверно. При использовании больших данных оператор using будет удалять поток до очистки буфера. Я 100% рекомендую явно вызывать флеш. – Ben Gripka 14 March 2015 в 06:27
  • 5
    Вам также не нужно использовать в строчном песеннике? например: using (var stringWriter = new StringWriter ()) – Steven Quick 13 August 2015 в 00:57
  • 6
    writer.Flush () НЕ избыточно, он ДОЛЖЕН быть там. Без Flush может случиться так, что часть данных все еще находится в буфере StreamWriter, и файл удаляется, а некоторые данные отсутствуют. – qub1n 14 November 2015 в 21:49
  • 7
    Это сводило меня с ума. Я не мог понять, почему это было всегда пусто. Тогда понял, что после прочтения вашего ответа у меня не было конструктора без параметров. Спасибо. – Andy 23 January 2017 в 20:45
  • 8
    @jammycakes Нет! Когда вы бросаете новый Exception, вы расширили StackTrace с помощью метода «Сериализовать & lt; & gt;». – user2190035 2 March 2017 в 14:31
  • 9
    @ user2190035 наверняка, если он должен был прорваться в метод расширения, там начнется трассировка стека? & quot; Расширение трассировки стека " с попыткой кажется ненужной? – Nova 27 October 2017 в 07:10

Я начну с ответа на копию Ben Gripka:

public void Save(string FileName)
{
    using (var writer = new System.IO.StreamWriter(FileName))
    {
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();
    }
}

Я использовал этот код раньше. Но реальность показала, что это решение немного проблематично. Обычно большинство программистов просто сериализуют настройки при сохранении и десериализации настроек при загрузке. Это оптимистический сценарий. Как только сериализация завершилась неудачно, по какой-то причине файл частично написан, файл XML не является полным и недействителен. В результате десериализация XML не работает, и ваше приложение может сработать при запуске. Если файл не огромен, я предлагаю сначала сериализовать объект в MemoryStream, а затем записать поток в файл. Этот случай особенно важен, если есть некоторая сложная пользовательская сериализация. Вы никогда не сможете проверить все случаи.

public void Save(string fileName)
{
    //first serialize the object to memory stream,
    //in case of exception, the original file is not corrupted
    using (MemoryStream ms = new MemoryStream())
    {
        var writer = new System.IO.StreamWriter(ms);    
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();

        //if the serialization succeed, rewrite the file.
        File.WriteAllBytes(fileName, ms.ToArray());
    }
}

Дезериализация в сценарии реального мира должна рассчитываться с поврежденным файлом сериализации, это происходит когда-то. Функция загрузки, предоставленная Бен Грипкой, прекрасна.

public static [ObjectType] Load(string fileName)
{
    using (var stream = System.IO.File.OpenRead(fileName))
    {
        var serializer = new XmlSerializer(typeof([ObjectType]));
        return serializer.Deserialize(stream) as [ObjectType];        
    }    
}

И это может быть обернуто некоторым сценарием восстановления. Он подходит для файлов настроек или других файлов, которые могут быть удалены в случае возникновения проблем.

public static [ObjectType] LoadWithRecovery(string fileName)
{
    try
    {
        return Load(fileName);
    }
    catch(Excetion)
    {
        File.Delete(fileName); //delete corrupted settings file
        return GetFactorySettings();
    }
}
13
ответ дан qub1n 21 August 2018 в 08:11
поделиться
88
ответ дан Peter Mortensen 1 November 2018 в 03:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: