C# 重写ActionResult而不缓存数据
我已经创建了一个从C# 重写ActionResult而不缓存数据,c#,asp.net,asp.net-mvc,actionresult,C#,Asp.net,Asp.net Mvc,Actionresult,我已经创建了一个从ActionResult派生的sitemapreult类。它允许调用者添加任意数量的URL资源,然后以XML格式输出站点地图数据 public class SitemapResult : ActionResult { private List<SitemapUrl> SitemapItems; public SitemapResult() { SitemapItems = new List<SitemapUrl>
ActionResult
派生的sitemapreult
类。它允许调用者添加任意数量的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
}
}
}
公共类SitemapResult:ActionResult
{
私有列表站点映射项;
公共站点映射结果()
{
SitemapItems=新列表();
}
public void AddUrl(字符串url,DateTime?lastModified=null,SitemapFrequency?frequency=null,double?priority=null)
{
AddUrl(新站点映射url(url、上次修改、频率、优先级));
}
公共覆盖无效ExecuteSult(ControllerContext上下文)
{
context.HttpContext.Response.ContentType=“text/xml;charset=utf-8”;
使用(XmlWriter=XmlWriter.Create(context.HttpContext.Response.Output))
{
//TODO:将站点地图数据写入输出
}
}
}
问题是该类存储所有URL,直到调用executesult()
。如果我可以在添加响应时将每个URL写入响应,而不是将它们全部保存在内存中,然后一次写入所有内容,那么似乎效率会更高
有人知道有什么好的例子可以覆盖
ActionResult
,在响应可用时将数据写入响应吗?在这种情况下,我认为executesult()
根本不需要编写任何东西。您试图实现的是在视图(自定义视图)中构建模型。。。这不是一个好的做法。。。在MVC中,控制器负责构建模型并将其传递给视图。。。视图负责显示模型,并且应该尽可能少地使用逻辑
似乎如果我能把每个URL都写到 当它们被添加时的响应,而不是将它们全部保存在内存和 然后立即写下每件事 为什么??您需要将
SitemapItems
保存在内存中的某个位置,因此即使您将它们写入响应,它们仍会保存在内存中,直到您返回响应为止。。。我认为将整个列表一次序列化为XML会更有效,而不是逐个序列化每个SitemapUrl
您的问题有一个非常优雅的解决方案: 然后在控制器中构建模型,并将其传递给视图:
return new SitemapResult(SitemapItems);
如果要直接写入响应,可以在控制器中执行:
public MyController : controller
{
public void GetSiteMapUrls()
{
XmlSerializer serializer = new XmlSerializer(SitemapItems.GetType());
Response.ContentType = "text/xml";
serializer.Serialize(Response.Output, SitemapItems);
}
}
除非您在创建结果时传递响应,否则它只能通过ExecuteSult中的上下文访问响应method@Nkosi:我已经添加了基本布局,但我不确定您到底想看什么,因为您没有说。您可以存储一个
Func
并在executesult
中调用它。然后,对AddUrl
的调用将替换为yield return
s。(一个简单的IEnumerable
也可以,实际上,如果没有太多的设置来启动枚举,那么Func
就没有必要了。)SitemapItems
可以作为构造函数arg传递,并用于填充结果。我想知道这是否是过早的优化。我正在从各种来源获取数据,包括数据库。除了在将结果发送到响应之前缓存结果外,不需要将整个列表存储在内存中。显然,不缓存这些数据似乎更有效。此外,如果有一种方法在我收集数据时发送数据,而不是先缓存数据,那么速度会快得多。你发布的代码与我发布的代码非常相似。我的只是帮助收集数据。我可以尝试使用XmlWriter的XmlSerializer,但正如我所描述的,这似乎不是最有效的方法。。。你有一个URL列表,对吗?您不想将整个列表存储在内存中,但整个列表不是要以序列化xml的形式添加到响应中吗?我构建了一个URL列表。但这一额外步骤对我来说似乎没有必要。我宁愿将找到的每个URL发送到响应,而不是将其存储在内存中的单独集合中。如果不需要URL列表,可以直接将其写入控制器中的响应(请参阅更新的答案)。如果我理解正确,您需要的是在SiteMapResult中构建序列化的XML列表。。。MVC不是这样设计的。模型应该内置在控制器中并传递给视图。
public MyController : controller
{
public void GetSiteMapUrls()
{
XmlSerializer serializer = new XmlSerializer(SitemapItems.GetType());
Response.ContentType = "text/xml";
serializer.Serialize(Response.Output, SitemapItems);
}
}