我已经创建了一个SitemapResult
派生的ActionResult
类。它允许调用者添加任意数量的URL资源,然后以XML格式输出站点地图数据。
public class SitemapResult : ActionResult
{
private List<SitemapUrl> SitemapItems;
public SitemapResult()
{
SitemapItems = new List<SitemapUrl>();
}
public void AddUrl(string url, DateTime? lastModified = null, SitemapFrequency? frequency = null, double? priority = null)
{
AddUrl(new SitemapUrl(url, lastModified, frequency, priority));
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = "text/xml; charset=utf-8";
using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
{
// TODO: Write sitemap data to output
}
}
}
问题是该类存储所有URL,直到调用ExecuteResult()
为止。如果我可以在添加响应时将每个URL写入响应中,而不是将它们全部保留在内存中,然后一次写入所有内容,那似乎会更有效率。
有人知道重写ActionResult
以在响应可用时将数据写入响应的任何好例子吗?在这种情况下,我认为ExecuteResult()
根本不需要写任何东西。
答案 0 :(得分:1)
您要实现的目标是在视图(自定义视图)中构建模型……这不是一个好习惯……在MVC中,控制器负责构建模型并将其传递给视图。视图负责显示模型,并且逻辑应尽可能少。
如果我可以将每个URL写到 添加它们时的响应,而不是将它们全部保存在内存中, 然后一次写所有东西。
为什么?您需要将SitemapItems
保留在内存中的某个位置,因此即使将它们写入响应中,它们也仍会保留在内存中,直到您返回响应为止。我认为序列化整个列表会更有效。一次性转换为XML,而不是分别序列化每个SitemapUrl
。
您在this pluralsight course上的问题有一个非常优雅的解决方案:
public class SitemapResult : ActionResult
{
private object _data;
public SitemapResult(object data)
{
_data = data;
}
public override void ExecuteResult(ControllerContext context)
{
// you can use reflection to determine object type
XmlSerializer serializer = new XmlSerializer(_data.GetType());
var response = context.HttpContext.Response;
response.ContentType = "text/xml";
serializer.Serialize(response.Output, _data);
}
}
然后您在控制器中构建模型,并将其传递给视图:
return new SitemapResult(SitemapItems);
如果您想直接写入Response,则可以在控制器中进行:
public MyController : controller
{
public void GetSiteMapUrls()
{
XmlSerializer serializer = new XmlSerializer(SitemapItems.GetType());
Response.ContentType = "text/xml";
serializer.Serialize(Response.Output, SitemapItems);
}
}