sourcetip

의 컨트롤러 작업에서 XML을 작업 결과로 반환하시겠습니까?

fileupload 2023. 5. 3. 21:40
반응형

의 컨트롤러 작업에서 XML을 작업 결과로 반환하시겠습니까?

ASP에서 컨트롤러의 작업에서 XML을 반환하는 가장 좋은 방법은 무엇입니까?NET MVC?XML용이 아닌 JSON을 반환하는 좋은 방법이 있습니다. XML을 보기를 통해 라우팅해야 합니까? 아니면 모범 사례가 아닌 응답 방법을 사용해야 합니까?쓰기?

return this.Content(xmlString, "text/xml");

MVContrib의 XmlResult Action을 사용합니다.

참고로 다음은 해당 코드입니다.

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);
        }
    }
}

우수한 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);
}

한 사용자 지정 재용사정의자용가ActionResultXML을 직렬화합니다.

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 Contribute에는 XmlResult(및 기타)가 있습니다.http://www.codeplex.com/MVCContrib 을 살펴보십시오.

저는 최근에 Sitecore 항목과 하위 항목에서 XmlDocument를 생성하고 이를 ActionResult 컨트롤러에서 파일로 반환하는 Sitecore 프로젝트를 위해 이 작업을 수행해야 했습니다.내 솔루션:

public virtual ActionResult ReturnXml()
{
    return File(Encoding.UTF8.GetBytes(GenerateXmlFeed().OuterXml), "text/xml");
}

다음 방법 중 하나를 사용합니다.

    public ContentResult GetXml()
    {
        string xmlString  = "your xml data";
        return Content(xmlString, "text/xml");
    }

또는

    public string GetXml()
    {
        string xmlString = "your xml data";
        Response.ContentType = "text/xml";
        return xmlString;
    }

마침내 이 일을 할 수 있게 되었고, 다른 사람들의 고통을 덜어주기 위해 여기서 어떻게 문서화할 것인지 생각했습니다.

환경

  • VS2012
  • SQL Server 2008 R2
  • .NET 4.5
  • ASP.NET MVC4(레이저)
  • 윈도우 7

지원되는 웹 브라우저

  • 파이어폭스 23
  • IE 10
  • 크롬 29
  • 오페라 16
  • Safari 5.1.7(윈도우즈의 마지막 버전?)

제 작업은 UI 버튼을 클릭하고 컨트롤러에서 메서드를 호출한 다음 xslt 변환을 통해 MS-Excel XML을 반환하도록 하는 것이었습니다.반환된 MS-Excel XML을 사용하면 브라우저에서 열기/저장 대화 상자가 팝업됩니다.이 작업은 위에 나열된 모든 브라우저에서 작동해야 했습니다.

처음에 저는 Ajax와 함께 파일 이름에 대한 "다운로드" 속성을 가진 동적 앵커를 만들려고 했지만, 그것은 5개 브라우저 중 약 3개(FF, 크롬, 오페라)에서만 작동했고 IE나 Safari에서는 작동하지 않았습니다.그리고 앵커의 클릭 이벤트를 프로그래밍 방식으로 실행하여 실제 "다운로드"를 발생시키는 데 문제가 있었습니다.

결국 제가 한 일은 "보이지 않는" 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을 작업 결과로 반환하시겠습니까?

내 컨트롤러 메서드(액션 결과 반환)

  • 키 매개 변수를 XML을 생성하는 SQL Server 저장 프로시저로 전달합니다.
  • 그런 다음 XML이 xslt를 통해 MS-Excel xml(XmlDocument)로 변환됩니다.
  • 수정된 XmlActionResult의 인스턴스를 만들고 이를 반환합니다.

    XmlActionResult = new XmlActionResult(excelXML, "application/vnd.ms -syslog"); 문자열 버전 = DateTime.지금.ToString("dd_MMM_yyyy_hhmmsstt"); 문자열 fileMask = "LabelExport_{0.xml";
    결과.DownloadFilename = 문자열입니다.형식(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);
}

기본적으로 그게 다였습니다.다른 사람들에게 도움이 되길 바랍니다.

스트림 및 기타 모든 기능을 사용할 수 있는 간단한 옵션return File(stream, "text/xml");.

간단한 방법은 다음과 같습니다.

        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");

XDocument의 Save() 방법을 사용하는 Drew Noakes의 답변의 작은 변형입니다.

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)
    }
}

언급URL : https://stackoverflow.com/questions/134905/return-xml-from-a-controllers-action-in-as-an-actionresult

반응형