Как лучше всего вернуть XML из действия контроллера в ASP.NET MVC? Есть хороший способ вернуть JSON, но не для XML. Действительно ли мне нужно направлять XML через представление, или я должен использовать не самый лучший способ ответа.
asp.net
.net
xml
asp.net-mvc
Кен Рэндалл
источник
источник
XmlSerialiser
аннотаций и членов может быть сложно поддерживать. С тех пор, как Люк опубликовал этот ответ (около четырех лет назад), Linq to XML зарекомендовал себя как более элегантная и мощная замена для большинства распространенных сценариев. Посмотрите мой ответ, чтобы увидеть, как это сделать.return this.Content(xmlString, "text/xml");
источник
application/xml
Вместо этого вы можете использовать mimetype.Если вы создаете XML, используя отличную структуру Linq-to-XML, этот подход будет полезен.
Я создаю
XDocument
метод действия.public ActionResult MyXmlAction() { // Create your own XDocument according to your requirements var xml = new XDocument( new XElement("root", new XAttribute("version", "2.0"), new XElement("child", "Hello World!"))); return new XmlActionResult(xml); }
Этот многоразовый пользовательский
ActionResult
сериализует XML для вас.public sealed class XmlActionResult : ActionResult { private readonly XDocument _document; public Formatting Formatting { get; set; } public string MimeType { get; set; } public XmlActionResult(XDocument document) { if (document == null) throw new ArgumentNullException("document"); _document = document; // Default values MimeType = "text/xml"; Formatting = Formatting.None; } public override void ExecuteResult(ControllerContext context) { context.HttpContext.Response.Clear(); context.HttpContext.Response.ContentType = MimeType; using (var writer = new XmlTextWriter(context.HttpContext.Response.OutputStream, Encoding.UTF8) { Formatting = Formatting }) _document.WriteTo(writer); } }
Вы можете указать тип MIME (например,
application/rss+xml
) и должен ли вывод быть с отступом, если вам нужно. Оба свойства имеют разумные значения по умолчанию.Если вам нужна кодировка, отличная от UTF8, то для нее тоже просто добавить свойство.
источник
application/octet-stream
принудительного скачивания. Я не знаю, какой тип MIME запускает Excel, но вы сможете достаточно легко найти его в Интернете.Если вас интересует только возврат xml через запрос, и у вас есть «кусок» xml, вы можете просто сделать (как действие в вашем контроллере):
источник
В MVC Contrib есть XmlResult (и многое другое). Взгляните на http://www.codeplex.com/MVCContrib
источник
Недавно мне пришлось сделать это для проекта Sitecore, который использует метод для создания XmlDocument из элемента Sitecore и его дочерних элементов и возвращает его из контроллера ActionResult в виде файла. Мое решение:
источник
Наконец-то удалось получить эту работу, и я подумал, что запишу, как здесь, в надежде спасти других от боли.
Окружающая среда
Поддерживаемые веб-браузеры
Моя задача заключалась в нажатии кнопки пользовательского интерфейса, вызове метода на моем контроллере (с некоторыми параметрами), а затем в том, чтобы он возвращал XML MS-Excel через преобразование xslt. После этого возвращенный MS-Excel XML вызовет в браузере всплывающее диалоговое окно «Открыть / сохранить». Это должно было работать во всех браузерах (перечисленных выше).
Сначала я попытался использовать Ajax и создать динамический якорь с атрибутом «загрузить» для имени файла, но это сработало только для 3 из 5 браузеров (FF, Chrome, Opera), а не для IE или Safari. И были проблемы с попыткой программно запустить событие Click привязки, чтобы вызвать фактическую «загрузку».
В итоге я использовал «невидимый» IFRAME, и он работал во всех 5 браузерах!
Итак, вот что я придумал: [обратите внимание, что я ни в коем случае не гуру html / javascript и включил только соответствующий код]
HTML (фрагмент соответствующих битов)
<div id="docxOutput"> <iframe id="ifOffice" name="ifOffice" width="0" height="0" hidden="hidden" seamless='seamless' frameBorder="0" scrolling="no"></iframe></div>
JAVASCRIPT
C # SERVER-SIDE (фрагмент кода) @Drew создал настраиваемый ActionResult под названием XmlActionResult, который я модифицировал для своих целей.
Вернуть XML из действия контроллера в виде ActionResult?
Мой метод контроллера (возвращает ActionResult)
создает экземпляр измененного XmlActionResult и возвращает его
Результат XmlActionResult = новый результат XmlActionResult (excelXML, «application / vnd.ms-excel»); строка version = DateTime.Now.ToString ("dd_MMM_yyyy_hhmmsstt"); строка fileMask = "LabelExport_ {0} .xml";
result.DownloadFilename = string.Format (fileMask, версия); вернуть результат;
Основная модификация класса XmlActionResult, созданная @Drew.
public override void ExecuteResult(ControllerContext context) { string lastModDate = DateTime.Now.ToString("R"); //Content-Disposition: attachment; filename="<file name.xml>" // must set the Content-Disposition so that the web browser will pop the open/save dialog string disposition = "attachment; " + "filename=\"" + this.DownloadFilename + "\"; "; context.HttpContext.Response.Clear(); context.HttpContext.Response.ClearContent(); context.HttpContext.Response.ClearHeaders(); context.HttpContext.Response.Cookies.Clear(); context.HttpContext.Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);// Stop Caching in IE context.HttpContext.Response.Cache.SetNoStore();// Stop Caching in Firefox context.HttpContext.Response.Cache.SetMaxAge(TimeSpan.Zero); context.HttpContext.Response.CacheControl = "private"; context.HttpContext.Response.Cache.SetLastModified(DateTime.Now.ToUniversalTime()); context.HttpContext.Response.ContentType = this.MimeType; context.HttpContext.Response.Charset = System.Text.UTF8Encoding.UTF8.WebName; //context.HttpContext.Response.Headers.Add("name", "value"); context.HttpContext.Response.Headers.Add("Last-Modified", lastModDate); context.HttpContext.Response.Headers.Add("Pragma", "no-cache"); // HTTP 1.0. context.HttpContext.Response.Headers.Add("Expires", "0"); // Proxies. context.HttpContext.Response.AppendHeader("Content-Disposition", disposition); using (var writer = new XmlTextWriter(context.HttpContext.Response.OutputStream, this.Encoding) { Formatting = this.Formatting }) this.Document.WriteTo(writer); }
Вот и все. Надеюсь, это поможет другим.
источник
Простой вариант, который позволит вам использовать потоки и все такое
return File(stream, "text/xml");
.источник
Вот простой способ сделать это:
источник
ms
напрямую, а не копировать на новый? Оба объекта будут иметь одинаковое время жизни.ms.Position=0
и вы сможете вернуть исходный поток памяти. Тогда вы можетеreturn new FileStreamResult(ms,"text/xml");
Небольшой вариант ответа Дрю Ноукса , использующий метод Save () XDocument.
источник