首页 > 解决方案 > 在不缓存数据的情况下覆盖 ActionResult

问题描述

我创建了一个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()根本不需要写任何东西。

标签: c#asp.netasp.net-mvcactionresult

解决方案


您要实现的目标是在视图(自定义视图)中构建模型...这不是一个好习惯...在 MVC 中,控制器负责构建模型并将其传递给视图...视图是负责显示模型,并应尽可能少的逻辑。


如果我可以在添加响应时将每个 URL 写入响应,而不是将它们全部保存在内存中然后一次写入所有内容,似乎会更有效。

为什么?您需要保留SitemapItems在内存中的某个位置,因此即使您将它们写入响应,它们仍会保留在内存中,直到您返回响应......我认为一次将整个列表序列化为 XML 会更有效,而不是单独序列化每个SitemapUrl


关于这个复数课程,您的问题有一个非常优雅的解决方案:

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);

如果您想直接写入响应,您可以在控制器中执行此操作:

public MyController : controller
{
    public void GetSiteMapUrls()
    {
        XmlSerializer serializer = new XmlSerializer(SitemapItems.GetType());
        Response.ContentType = "text/xml";
        serializer.Serialize(Response.Output, SitemapItems);
    }
}

推荐阅读