ASP.NET MVC의 컨트롤러 작업에서 XML을 반환하는 가장 좋은 방법은 무엇입니까? JSON을 반환하는 좋은 방법이 있지만 XML은 아닙니다. 실제로 XML을 View를 통해 라우팅해야합니까, 아니면 최선의 방법으로 Response를 작성해야합니까?
답변
MVCContrib 의 XmlResult 조치를 사용하십시오 .
여기에 그들의 코드가 있습니다 :
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); } } }
답변
return this.Content(xmlString, "text/xml");
답변
뛰어난 Linq-to-XML 프레임 워크를 사용하여 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 이외의 인코딩이 필요한 경우 해당 속성을 추가하는 것도 간단합니다.
답변
요청을 통해서만 XML을 반환하고 xml “청크”가있는 경우 컨트롤러에서 작업으로 수행 할 수 있습니다.
public string Xml()
{
Response.ContentType = "text/xml";
return yourXmlChunk;
}
답변
MVC Contrib에는 XmlResult (및 그 이상)가 있습니다. http://www.codeplex.com/MVCContrib 를 보십시오
답변
최근에 Sitecore 항목 및 해당 하위 항목에서 XmlDocument를 작성하고 컨트롤러 ActionResult에서 파일로이를 리턴하는 메소드를 사용하는 Sitecore 프로젝트에 대해이 작업을 수행해야했습니다. 내 해결책 :
public virtual ActionResult ReturnXml()
{
return File(Encoding.UTF8.GetBytes(GenerateXmlFeed().OuterXml), "text/xml");
}
답변
마지막 으로이 작업을 수행하고 다른 사람들이 고통을 덜기 위해 어떻게 여기에 문서화 할 것이라고 생각했습니다.
환경
- VS2012
- SQL Server 2008R2
- .NET 4.5
- ASP.NET MVC4 (레이저)
- 윈도우 7
지원되는 웹 브라우저
- 파이어 폭스 23
- IE 10
- 크롬 29
- 오페라 16
- Safari 5.1.7 (Windows 용 마지막 것)
내 작업은 ui 버튼 클릭으로 내 컨트롤러에서 메소드를 호출하고 (매개 변수 포함) xslt 변환을 통해 MS-Excel XML을 반환하도록합니다. 반환 된 MS-Excel XML은 브라우저가 열기 / 저장 대화 상자를 팝업하게합니다. 이것은 위에 나열된 모든 브라우저에서 작동해야했습니다.
처음에는 Ajax로 파일 이름에 대한 “다운로드”속성을 가진 동적 앵커를 만들려고 시도했지만 IE 또는 Safari가 아닌 5 개의 브라우저 (FF, Chrome, Opera) 중 약 3 개에서만 작동했습니다. 그리고 앵커의 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>
자바 스크립트
//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 (코드 조각) @Drew는 XmlActionResult라는 사용자 지정 ActionResult를 만들었습니다.
컨트롤러의 액션에서 XML을 ActionResult로 반환 하시겠습니까?
내 컨트롤러 방법 (ActionResult 반환)
- XML을 생성하는 SQL Server 저장 프로 시저에 keys 매개 변수를 전달합니다.
- XML은 xslt를 통해 MS-Excel xml (XmlDocument)로 변환됩니다.
-
수정 된 XmlActionResult의 인스턴스를 만들어 반환
XmlActionResult 결과 = 새로운 XmlActionResult (excelXML, “application / vnd.ms-excel”); 문자열 버전 = DateTime.Now.ToString ( “dd_MMM_yyyy_hhmmsstt”); 문자열 fileMask = “LabelExport_ {0} .xml”;
result.DownloadFilename = string.Format (fileMask, 버전); 결과 반환;
@Drew가 생성 한 XmlActionResult 클래스의 주요 수정 사항입니다.
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);
}
기본적으로 그렇습니다. 그것이 다른 사람들을 돕기를 바랍니다.