Чтобы понять, что 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 не волшебным образом делает все ваши URL «хорошенькими». Это распространенное недоразумение. Если у вас есть эта ссылка на вашем веб-сайте:
нет ничего, что мог бы сделать mod_rewrite, чтобы сделать это красиво. Чтобы сделать это красивой ссылкой, вы должны:
/my/pretty/link
, используя любой из описанных выше методов. (Можно использовать mod_substitute
для преобразования исходящих HTML-страниц
Существует много возможностей mod_rewrite и очень сложные правила соответствия, которые вы можете создать, включая цепочку нескольких переписываний, проксирование запросов на совершенно другую услугу или машину, возврат определенных кодов статуса HTTP в виде ответов, перенаправление запросов и т. д. Это очень мощный и может быть использован для хорошего использования, если вы понимаете основной механизм запроса HTTP-ответа. Он не автоматически делает ваши ссылки симпатичными.
См. Официальную документацию для всех возможных флагов и опций.
Вы должны использовать 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
}
}
Вот хороший учебник о том, как это сделать
Для этого вам следует использовать класс System.Xml.Serialization.XmlSerializer
.
Класс расширения:
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){...}
XmlExtension.Serialize(foo);
, и все хорошо! Большое спасибо.
– ditto1977
26 December 2014 в 18:16
Вот базовый код, который поможет сериализовать объекты 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();
}
}
Или вы можете добавить этот метод к своему объекту:
public void Save(string filename)
{
var ser = new XmlSerializer(this.GetType());
using (var stream = new FileStream(filename, FileMode.Create))
ser.Serialize(stream, this);
}
Это немного сложнее, чем вызов метода 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;
}
}
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-файла в нужном месте.
мой рабочий код. Возвращает 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" />
Чтобы сериализовать объект, выполните:
using (StreamWriter myWriter = new StreamWriter(path, false))
{
XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
mySerializer.Serialize(myWriter, objectToSerialize);
}
Также помните, что для работы XmlSerializer нужен конструктор без параметров.
writer.Flush()
является избыточным в блоке using
- метод writer
Dispose()
будет очищать его для вас.
– bavaza
13 March 2015 в 11:38
Exception
, вы расширили StackTrace с помощью метода «Сериализовать & lt; & gt;».
– user2190035
2 March 2017 в 14:31
Я начну с ответа на копию 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();
}
}
XmlWriter writer = XmlWriter.Create(sww);
– Paul Hunt 27 June 2014 в 11:52using
люди используютusing
s! Утилизируйте эти объекты! – Liam 11 September 2014 в 17:25XmlTextWriter writer = new XmlTextWriter(sww) { Formatting = Formatting.Indented };
вместоXmlWriter writer = XmlWriter.Create(sww);
– Tono Nam 21 June 2015 в 15:22XmlWriter
инкапсулируетStringWriter
, вам не нужно распоряжаться обоими (первое использование избыточно), правильно? Я предполагаю, чтоXmlWriter
позаботится об утилизации ... – talles 10 November 2015 в 21:46XmlWriter
не инкапсулируетStringWriter
, он использует ваш переданныйStringWriter
и не имеет ожиданий / ответственности его распоряжаться. Кроме того,StringWriter
находится вне областиXmlWriter
, вы все еще можете захотеть его, когдаXmlWriter
будет удален, было бы плохое поведение дляXmlWriter
для размещения вашегоStringWriter
. Как правило, если вы заявляете то, что вам нужно, вы несете ответственность за его удаление. И неявное этому правилу, все, что вы не заявляете, вы не должны распоряжаться. Поэтому необходимы обеusing
s. – Arkaine55 24 May 2017 в 15:21