Return xml to preview browser Asp.net mvc

Asked

Viewed 690 times

4

I have the following situation, I need to provide an XML file to be viewable in the browser, without the user needing to download the file, I do this by saving the file in a directory and then I send the directory of this file and the browser opens as the example below:

public string getXml(int entradaId)
{
    try
    {
        var entrada = ctx.Entradas.Find(entradaId);
        string xml = entrada.Xml;

        var uploadPath = Server.MapPath("~/Content/Uploads");
        string caminhoArquivo = Path.Combine(@uploadPath, entrada.ChaveNota + "-nfe.xml");

        StreamWriter sw = new StreamWriter(caminhoArquivo);
        sw.Write(xml);
        sw.Flush();
        sw.Close();

        return "/Content/Uploads/" + entrada.ChaveNota + "-nfe.xml";
    }
    catch (Exception)
    {
        return "Xml Sem Entrada";
        throw;
    }
}

This works, but I believe it is not the right one. Because I end up not deleting the file and this will fill the folder with a while.

I need some way to return this XML for the Browser to open as a file and make the view available as an example.

But without me having to save the physical file.

  • entrada.Xml is a string?

  • @jbueno yes, It would be an XML saved in Sqlserver that returns me as a string.

  • Ready then =D

2 answers

4

You can create a Custom Actionresult for that reason.

An example would be:

We’ll call in our Custom ActionResult of XmlActionResult.

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

And in his controller, just do it this way:

public ActionResult Index()
{
    var xml = new XDocument(
            new XElement("root",
                new XAttribute("version", "2.0"),
                new XElement("child", "Hello World!")));

    return new XmlActionResult(xml);
}

Should your XML be a string, just convert before return, as the example below:

public ActionResult Index()
{
    String xml ="<Root>Root</Root>";

    return new XmlActionResult(XDocument.Parse(xml));
}

Remembering that you can also change the XmlActionResult to do the parse, if you wish.

If you want to see other ways, see these questions:

  • I thought dahora the answer. But I think it would be problematic for him to have to create an Xdocument since the string already exists. Anyway, it is mine +1 because it is very useful.

  • @jbueno Well remembered, I had not attacked this detail. Edited the answer.

  • @jbueno You can do it in a row. It doesn’t have to be with XDocument.

3


Really save XML just to show in the browser is not a good idea.

It is possible to simply return Content passing as first parameter to string XML.

public ActionResult GetXml(int entradaId)
{
    var entrada = ctx.Entradas.Find(entradaId);    
    return Content(entrada.Xml, "text/xml");
}   
  • Exactly what I needed, In my case I called via ajax to open in new tab, but I adapted the method and met me perfectly. Thank you

  • This approach is not good. There is no syntax and/or format check. XML may be malformed.

  • @The structure of XML is conferred at another stage of the process, even before being saved in BD it is validated so in return it always comes back correctly

Browser other questions tagged

You are not signed in. Login or sign up in order to post.