Return XML from a controller ' s action in as an ActionResult?
Jaki jest najlepszy sposób na zwrócenie XML z akcji kontrolera w ASP.NET MVC? Jest dobry sposób na zwrócenie JSON, ale nie dla XML. Czy naprawdę muszę przekierowywać XML przez Widok, czy powinienem zrobić nie najlepszy sposób odpowiedzi.Piszesz?
11 answers
Użyj MVCContrib'S Xmlresult Action.
Dla odniesienia tutaj jest ich kod:
public class XmlResult : ActionResult { private object objectToSerialize; /// <summary> /// Initializes a new instance of the <see cref="XmlResult"/> class. /// </summary> /// <param name="objectToSerialize">The object to serialize to XML.</param> public XmlResult(object objectToSerialize) { this.objectToSerialize = objectToSerialize; } /// <summary> /// Gets the object to be serialized to XML. /// </summary> public object ObjectToSerialize { get { return this.objectToSerialize; } } /// <summary> /// Serialises the object that was passed into the constructor to XML and writes the corresponding XML to the result stream. /// </summary> /// <param name="context">The controller context for the current request.</param> public override void ExecuteResult(ControllerContext context) { if (this.objectToSerialize != null) { context.HttpContext.Response.Clear(); var xs = new System.Xml.Serialization.XmlSerializer(this.objectToSerialize.GetType()); context.HttpContext.Response.ContentType = "text/xml"; xs.Serialize(context.HttpContext.Response.Output, this.objectToSerialize); } } }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 10:57:10
return this.Content(xmlString, "text/xml");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 10:58:12
Jeśli budujesz XML przy użyciu doskonałego frameworka Linq-to-XML, to takie podejście będzie pomocne.
Tworzę XDocument
w metodzie action.
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);
}
To wielokrotnego użytku, niestandardowe ActionResult
serializuje XML dla Ciebie.
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);
}
}
Możesz określić typ MIME (np. application/rss+xml
) i czy wyjście powinno być wcięte, jeśli zajdzie taka potrzeba. Obie właściwości mają rozsądne wartości domyślne.
Jeśli potrzebujesz kodowania innego niż UTF8, łatwo jest dodać właściwość dla tego też.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 13:26:25
Jeśli jesteś zainteresowany tylko zwróceniem xml poprzez żądanie, a masz swój XML "chunk", możesz po prostu zrobić (jako akcję w kontrolerze):
public string Xml()
{
Response.ContentType = "text/xml";
return yourXmlChunk;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-16 14:11:35
Jest XmlResult (i wiele więcej) w MVC Contrib. Spójrz na http://www.codeplex.com/MVCContrib
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-19 18:35:11
Ostatnio musiałem to zrobić dla projektu Sitecore, który używa metody do tworzenia XmlDocument z elementu Sitecore i jego potomków i zwraca go z kontrolera ActionResult jako plik. Moje rozwiązanie:
public virtual ActionResult ReturnXml()
{
return File(Encoding.UTF8.GetBytes(GenerateXmlFeed().OuterXml), "text/xml");
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-26 16:40:36
W końcu udało się zdobyć tę pracę i pomyślałem, że udokumentuję jak tutaj w nadziei na uratowanie innym bólu.
Środowisko
- VS2012
- SQL Server 2008R2
- . NET 4.5
- ASP.NET MVC4 (Razor)
- Windows 7
Obsługiwane Przeglądarki Internetowe
- FireFox 23
- IE 10
- Chrome 29
- Opera 16
- Safari 5.1.7 (ostatnia Dla Windows?)
Moje zadanie polegało na kliknięciu przycisku ui, wywołaniu metody na moim kontrolerze (z kilkoma paramami), a następnie zwróć MS-Excel XML poprzez transformację xslt. Zwracany MS-Excel XML spowoduje, że przeglądarka wyskakuje okno dialogowe Otwórz/Zapisz. To musiało działać we wszystkich przeglądarkach (wymienionych powyżej).
Na początku próbowałem z Ajax i stworzyć dynamiczny Anchor z atrybutem "download" dla nazwy pliku, ale to działało tylko dla około 3 z 5 przeglądarek (FF, Chrome, Opera), a nie dla IE czy Safari. I były problemy z próbowaniem programowo Uruchom Zdarzenie kliknięcia kotwicy, aby spowodować rzeczywiste "pobieranie".
To, co zrobiłem, to użycie "niewidzialnego" IFRAME i działało we wszystkich 5 przeglądarkach!
Oto, co wymyśliłem: [proszę zauważyć, że w żadnym wypadku nie jestem guru html / javascript i dodałem tylko odpowiedni kod]
HTML (fragment odpowiednich bitów)
<div id="docxOutput">
<iframe id="ifOffice" name="ifOffice" width="0" height="0"
hidden="hidden" seamless='seamless' frameBorder="0" scrolling="no"></iframe></div>
JAVASCRIPT
//url to call in the controller to get MS-Excel xml
var _lnkToControllerExcel = '@Url.Action("ExportToExcel", "Home")';
$("#btExportToExcel").on("click", function (event) {
event.preventDefault();
$("#ProgressDialog").show();//like an ajax loader gif
//grab the basket as xml
var keys = GetMyKeys();//returns delimited list of keys (for selected items from UI)
//potential problem - the querystring might be too long??
//2K in IE8
//4096 characters in ASP.Net
//parameter key names must match signature of Controller method
var qsParams = [
'keys=' + keys,
'locale=' + '@locale'
].join('&');
//The element with id="ifOffice"
var officeFrame = $("#ifOffice")[0];
//construct the url for the iframe
var srcUrl = _lnkToControllerExcel + '?' + qsParams;
try {
if (officeFrame != null) {
//Controller method can take up to 4 seconds to return
officeFrame.setAttribute("src", srcUrl);
}
else {
alert('ExportToExcel - failed to get reference to the office iframe!');
}
} catch (ex) {
var errMsg = "ExportToExcel Button Click Handler Error: ";
HandleException(ex, errMsg);
}
finally {
//Need a small 3 second ( delay for the generated MS-Excel XML to come down from server)
setTimeout(function () {
//after the timeout then hide the loader graphic
$("#ProgressDialog").hide();
}, 3000);
//clean up
officeFrame = null;
srcUrl = null;
qsParams = null;
keys = null;
}
});
C# SERVER-SIDE (fragment kodu) @Drew stworzył niestandardową akcję o nazwie XmlActionResult, który zmodyfikowałem do swojego celu.
Return XML from a controller ' s action in as an ActionResult?
Moja metoda kontrolera (zwraca ActionResult)
- przekazuje parametr keys do przechowywanego proc serwera SQL, który generuje XML XML jest następnie przekształcany przez xslt w MS-Excel xml (XmlDocument)
-
Tworzy instancję zmodyfikowanego XmlActionResult i zwraca ją
Xmlactionresult result = new XmlActionResult (excelXML, " aplikacja / vnd. ms-excel"); string version = DateTime.Teraz.ToString ("dd_mmm_yyy_hhmmsstt"); string fileMask = " LabelExport_{0}.xml";
wynik.DownloadFilename = string.Format (fileMask, wersja); return result;
Główna modyfikacja klasy xmlactionresult, którą stworzył @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);
}
To było w zasadzie to.
Mam nadzieję, że pomoże innym.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:06
Prosta opcja, która pozwoli Ci używać strumieni i wszystkiego, co jest return File(stream, "text/xml");
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-10 20:54:21
Oto prosty sposób na zrobienie tego:
var xml = new XDocument(
new XElement("root",
new XAttribute("version", "2.0"),
new XElement("child", "Hello World!")));
MemoryStream ms = new MemoryStream();
xml.Save(ms);
return File(new MemoryStream(ms.ToArray()), "text/xml", "HelloWorld.xml");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 19:22:37
Mała odmiana odpowiedzi od Drew Noakes , która używa metody Save () z XDocument.
public sealed class XmlActionResult : ActionResult
{
private readonly XDocument _document;
public string MimeType { get; set; }
public XmlActionResult(XDocument document)
{
if (document == null)
throw new ArgumentNullException("document");
_document = document;
// Default values
MimeType = "text/xml";
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Clear();
context.HttpContext.Response.ContentType = MimeType;
_document.Save(context.HttpContext.Response.OutputStream)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:32:20
Użyj jednej z tych metod
public ContentResult GetXml()
{
string xmlString = "your xml data";
return Content(xmlString, "text/xml");
}
Lub
public string GetXml()
{
string xmlString = "your xml data";
Response.ContentType = "text/xml";
return xmlString;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-05 19:51:12