27 December 2016

Creating an XmlResult for ASP.NET MVC

An XmlResult for ASP.NET MVC


Introduction

ActionResult methods in a Controller allow developers to easily return HTML results and JSON results via this.View(...) which creates a ViewResult and this.Json(...) which creates a JsonResult. [See the following MSDN resources for more information: Controller.View method and Controller.Json method.]

Unfortunately, there is no XmlResult type that derives from ActionResult.

Although there are WCF ways of returning XML in an ASP.NET MVC application, there are use cases where returning simple POX (plain old XML) from a call to an MVC Controller ActionResult is needed.

In this article, I'll show a simple way to create an XmlResult.



How to create an XmlResult


Requirements

An XmlResult should

  • Inherit from ViewResult,
  • Override the ExecuteResult method to write the XML,
  • Expose the object to serialize as a gettable property, and
  • Allow calling code to customize the XML produced.

The ExecuteResult override should

  • Do nothing if there is no object to serialize,
  • Use the XmlAttributeOverrides if there are any,
  • Set the ContentType of the Response to application/xml, and
  • Write the XML-serialized version of the object to serialize to the Output stream of the Response.



XmlResult Code

Below is code that meets these requirements:

// //-----------------------------------------------------------------------
// // <copyright file="XmlResult.cs" company="Stand Sure LLC">
// // Copyright (c) 2016. All rights reserved. "AS IS" code.
// // </copyright>
// //-----------------------------------------------------------------------
namespace ThreeWay.Common
{
using System.Web.Mvc;
using System.Xml.Serialization;
/// <summary>
/// XML view result.
/// </summary>
public class XmlResult : ViewResult
{
/// <summary>
/// The XML attribute overrides.
/// </summary>
private readonly XmlAttributeOverrides xmlAttributeOverrides;
/// <summary>
/// Initializes a new instance of the
/// <see cref="T:ThreeWay.Common.XmlResult"/> class.
/// </summary>
/// <param name="objectToSerialize">The object to serialize.</param>
/// <param name="xmlAttributeOverrides">XML attribute overrides
/// to allow customization of the XML.</param>
public XmlResult(
object objectToSerialize,
XmlAttributeOverrides xmlAttributeOverrides = null)
{
this.ObjectToSerialize = objectToSerialize;
this.xmlAttributeOverrides = xmlAttributeOverrides;
}
/// <summary>
/// Gets the object to serialize.
/// </summary>
/// <value>The object to serialize.</value>
public object ObjectToSerialize { get; private set; }
/// <summary>
/// Executes the result.
/// </summary>
/// <param name="context">The Controller Context.</param>
public override void ExecuteResult(ControllerContext context)
{
if (this.ObjectToSerialize != null)
{
var xs = this.xmlAttributeOverrides == null ?
new XmlSerializer(this.ObjectToSerialize.GetType()) :
new XmlSerializer(
this.ObjectToSerialize.GetType(),
this.xmlAttributeOverrides);
context.HttpContext.Response.ContentType = "application/xml";
xs.Serialize(
context.HttpContext.Response.Output,
this.ObjectToSerialize);
}
}
}
}
view raw XmlResult.cs hosted with ❤ by GitHub




How to extend Controller to easily return an XmlResult

It is desirable to be able to have an ActionResult method in a Controller be able to obtain an XmlResult via a this.XML(...) statement.

This can be accomplished via an Extension Method.


Requirements

The Controller.XML extension method should

  • Accept an object to serialize,
  • Optionally accept XmlAttributeOverrides, and
  • Return an XmlResult.


Code


Below is code that meets these requirements:

// //-----------------------------------------------------------------------
// // <copyright file="XmlResultControllerExtensions.cs"
// // company="Stand Sure LLC">
// // Copyright (c) 2016. All rights reserved.
// // </copyright>
// //-----------------------------------------------------------------------
namespace ThreeWay.Common
{
using System.Web.Mvc;
using System.Xml.Serialization;
public static class XmlResultControllerExtensions
{
public static XmlResult XML(
this Controller controller,
object model,
XmlAttributeOverrides xmlAttributeOverrides = null)
{
return new XmlResult(model, xmlAttributeOverrides);
}
}
}



Conclusion

This article shows a simple way to create an XmlResult to return XML that can be used within an ASP.NET MVC Controller, and a way to extend Controller to allow for easy use.

This approach is appropriate for simple needs and eliminates the need to write custom code each time XML is needed.

For more complicated needs, using a ContentResult offers a feasible approach.

No comments: