Użyj akcji XmlResult MVCContrib.
W celach informacyjnych 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);
}
}
}
XmlSerialiser
adnotacji i członków może być trudne do utrzymania. Odkąd Luke opublikował tę odpowiedź (około cztery lata temu), Linq to XML okazał się bardziej eleganckim i wydajnym zamiennikiem większości typowych scenariuszy. Sprawdź moją odpowiedź, aby zobaczyć przykład, jak to zrobić.źródło
application/xml
typu MIME.Jeśli budujesz XML przy użyciu doskonałego frameworka Linq-to-XML, to podejście będzie pomocne.
Tworzę metodę
XDocument
w akcji.Ten niestandardowy, wielokrotnego użytku,
ActionResult
serializuje XML dla Ciebie.Możesz określić typ MIME (np
application/rss+xml
) i określić, czy dane wyjściowe powinny 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, możesz łatwo dodać właściwość również do tego.
źródło
application/octet-stream
wymuszenia pobrania. Nie wiem, jaki typ MIME uruchamia program Excel, ale powinno być łatwo znaleźć go w Internecie.Jeśli chcesz zwrócić plik XML tylko za pośrednictwem żądania, a masz swój „fragment” xml, możesz po prostu wykonać (jako akcję w kontrolerze):
źródło
W MVC Contrib jest XmlResult (i wiele więcej). Spójrz na http://www.codeplex.com/MVCContrib
źródło
Musiałem to zrobić ostatnio dla projektu Sitecore, który używa metody do tworzenia XmlDocument z elementu Sitecore i jego elementów podrzędnych i zwraca go z kontrolera ActionResult jako plik. Moje rozwiązanie:
źródło
W końcu udało mi się zdobyć tę pracę i pomyślałem, że udokumentuję, jak tutaj w nadziei uratowania bólu innym.
Środowisko
Obsługiwane przeglądarki internetowe
Moje zadanie polegało na kliknięciu przycisku interfejsu użytkownika, wywołaniu metody na moim kontrolerze (z kilkoma parametrami), a następnie zwróceniu pliku XML MS-Excel za pośrednictwem transformacji xslt. Zwrócony plik XML MS-Excel spowodowałby wówczas wyświetlenie okna dialogowego Otwórz / Zapisz w przeglądarce. Musiało to działać we wszystkich przeglądarkach (wymienionych powyżej).
Na początku próbowałem z Ajaxem i stworzyć dynamiczną kotwicę z atrybutem „download” dla nazwy pliku, ale działało to tylko dla około 3 z 5 przeglądarek (FF, Chrome, Opera), a nie dla IE czy Safari. Występowały też problemy z próbą programowego wywołania zdarzenia Click kotwicy w celu spowodowania faktycznego „pobrania”.
Skończyło się na tym, że użyłem „niewidzialnej” ramki IFRAME i zadziałało we wszystkich 5 przeglądarkach!
Oto, co wymyśliłem: [pamiętaj, że w żadnym wypadku nie jestem guru html / javascript i włączyłem tylko odpowiedni kod]
HTML (fragment odpowiednich bitów)
JAVASCRIPT
C # SERVER-SIDE (fragment kodu) @Drew utworzył niestandardową ActionResult o nazwie XmlActionResult, którą zmodyfikowałem w swoim celu.
Zwrócić XML z akcji kontrolera w postaci ActionResult?
Metoda My Controller (zwraca ActionResult)
tworzy wystąpienie zmodyfikowanego XmlActionResult i zwraca je
XmlActionResult result = new XmlActionResult (excelXML, "application / vnd.ms-excel"); string version = DateTime.Now.ToString ("dd_MMM_yyyy_hhmmsstt"); string fileMask = "LabelExport_ {0} .xml";
result.DownloadFilename = string.Format (fileMask, wersja); wynik zwrotu;
Główna modyfikacja klasy XmlActionResult utworzonej przez @Drew.
To było w zasadzie to. Mam nadzieję, że to pomaga innym.
źródło
Prosta opcja, która pozwoli Ci korzystać ze strumieni i tego wszystkiego
return File(stream, "text/xml");
.źródło
Oto prosty sposób na zrobienie tego:
źródło
ms
bezpośrednio, zamiast kopiować go do nowego? Oba obiekty będą miały taką samą żywotność.ms.Position=0
i możesz zwrócić oryginalny strumień wspomnień. Wtedy możeszreturn new FileStreamResult(ms,"text/xml");
Mała odmiana odpowiedzi od Drew Noakes, która używa metody Save () z XDocument.
źródło