Reputation: 11864
I am displaying charts that load the data asynchronously because the searches are the work to fetch the data is quite heavy. The data has to be return as XML to make the chart library happy.
My ActionMethods return a ContentResult with the type set as text/xml. I build my Xml using Linq to XML and call ToString. This works fine but it's not ideal to test.
I have another idea to achieve this which would be to return a view that builds my XML using the XSLT View engine.
I am curious and I always try to do the things "the right way". So how are you guys handling such scenarios?
Do you implement a different ViewEngine (like xslt) to build your XML or do you Build your XML inside your controller (Or the service that serves your controller)?
EDIT :
Since I need this to pass the data to a Charting Library, I have to follow their xml structure. Their notation is not the way i want to build my model classes at all. That's why I build the XML myself using Linq to XML and wonder if a template would be better.
Simple serialization is not what I look for
Upvotes: 2
Views: 1019
Reputation: 311007
Given that you're using Linq to XML to compose the response XML, you might like to use the same approach I do.
I create a XDocument
in the action method.
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);
}
This reusable, custom ActionResult
serialises the XDocument
as XML text to the response stream for you.
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);
}
}
You can specify a MIME type (such as application/rss+xml
) and whether the output should be indented if you need to. Both properties have sensible defaults.
If you need an encoding other than UTF8, then it's simple to add a property for that too.
Upvotes: 0
Reputation: 20674
I use my own custom ActionResult, which you could modify to your needs.
public class XmlDataResult : ActionResult
{
private readonly object _stringToConvertToXml;
public XmlDataResult(string stringToConvertToXml)
{
_stringToConvertToXml = stringToConvertToXml;
}
public object StringToConvertToXml
{
get { return _stringToConvertToXml; }
}
public override void ExecuteResult(ControllerContext context)
{
if (_stringToConvertToXml != null)
{
context.HttpContext.Response.Clear();
context.HttpContext.Response.ContentType = "text/xml";
context.HttpContext.Response.Write(_stringToConvertToXml);
}
}
}
Upvotes: 1
Reputation: 1038930
Write a custom action result:
public class XmlActionResult : ActionResult
{
public XmlActionResult(object data)
{
Data = data;
}
public object Data { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = "text/xml";
// TODO: Use your preferred xml serializer
// to serialize the model to the response stream :
// context.HttpContext.Response.OutputStream
}
}
And in your controller action:
public ActionResult Index()
{
var model = _repository.GetModel();
return new XmlActionResult(model);
}
Upvotes: 5