J'utilise asp.net mvc comme mon site web html (affichage par défaut du moteur) et mon point de terminaison de service. Le point de terminaison de service est utilisé par mon WPF et Silverlight clients par injection "content-type=text/xml" dans l'en-tête d'une requête WebClient (voir ScottGu du post sur la consommation d'un service dans SL, qui a inspiré cette approche). J'ai trouvé quelque part sur le net, un peu de code qui remplace la OnActionExecuted événement comme celui-ci:
public class JsonOrXml : ActionFilterAttribute
{
private static UTF8Encoding UTF8 = new UTF8Encoding(false);
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// setup the request, view and data
HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
ViewResult view = (ViewResult)(filterContext.Result);
var data = view.ViewData.Model;
String contentType = request.ContentType ?? string.Empty;
// JSON
if (contentType.Contains("application/json") || (string)view.ViewData["FORMAT"] == "json")
{
filterContext.Result = new JsonResult
{
Data = data
};
}
// POX
else if (contentType.Contains("text/xml") || (string)view.ViewData["FORMAT"] == "xml")
{
// MemoryStream to encapsulate as UTF-8 (default UTF-16)
// http://stackoverflow.com/questions/427725/
//
// MemoryStream also used for atomicity but not here
// http://stackoverflow.com/questions/486843/
//using (MemoryStream stream = new MemoryStream(500))
//{
// using (var xmlWriter =
// XmlTextWriter.Create(stream,
// new XmlWriterSettings()
// {
// OmitXmlDeclaration = false,
// Encoding = UTF8,
// Indent = true
// }))
// {
// new XmlSerializer(data.GetType()).Serialize(xmlWriter, data);
// }
// filterContext.Result = new ContentResult
// {
// ContentType = "text/xml",
// Content = UTF8.GetString(stream.ToArray()),
// ContentEncoding = UTF8
// };
//}
XmlDeclaration xmlDecl = new XmlDocument().CreateXmlDeclaration("1.0", "UTF-8", "yes");
filterContext.Result = new ContentResult
{
ContentType = "text/xml",
Content = xmlDecl.OuterXml + data.ToString(),
ContentEncoding = UTF8
};
}
}
}
Donc, le commentaire d'un élément est le code que j'ai trouvé à voir le stackoverflow liens de où je l'ai eu :)
J'ai changé la méthode ToString() sur l'ensemble de mon business objects pour revenir chaîne de caractères représentant la manière dont l'entreprise objet aimerais représenter lui-même comme du xml. WCF accomplit ceci grâce à des attributs, mais je voulais une solution de nettoyage qui ne repose pas sur la réflexion ET je ne voulais pas avoir à la fois un projet de site web et d'un projet WCF - le problème de la deux projets, c'est qu'il était difficile de les garder en synchronisation avec le respect de la fonctionnalité - je me demande, "pourquoi ne pas le service de me permettre de filtrer les résultats de ma recherche comme le site n'?"
Je suis très intéressé par d'autres commentaires sur cette approche :)
Voici un exemple d'un objet de l'entreprise:
public class ContentFile : Entity
{
public ContentBook BelongsToBook { get; set; }
public string FileName { get; set; }
public XElement FileXml { get; set; }
public Binary FileData { get; set; }
public List<ContentFile> Versions { get; set; }
public List<ContentNode> ContentNodes { get; set; }
public override string ToString()
{
return this.ToString(SaveOptions.DisableFormatting);
}
public string ToString(SaveOptions options)
{
XElement xml = XElement.Parse("<contentFile id=\"" + Id.ToString() + "" + "\" />");
xml.Add(new XElement("fileName", FileName));
xml.Add(new XElement("fileStructure", FileXml));
xml.Add(base.ToString(options));
return xml.ToString(options);
}
}