3 votes

Remplacer l'ActionResult sans mettre les données en cache

J'ai créé un SitemapResult qui dérive de ActionResult . Il permet à l'appelant d'ajouter n'importe quel nombre de ressources URL, puis il produit des données sitemap au format 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

        }
    }
}

Le problème est que la classe stocke toutes les URLs jusqu'à ce que ExecuteResult() est appelé. Il me semble qu'il serait plus efficace d'écrire chaque URL dans la réponse au fur et à mesure qu'elles sont ajoutées, plutôt que de les garder en mémoire et de tout écrire en même temps.

Est-ce que quelqu'un connaît de bons exemples de contournement ActionResult pour écrire les données dans la réponse dès qu'elles sont disponibles ? Dans ce cas, je pense que ExecuteResult() n'auront pas besoin d'écrire quoi que ce soit.

1voto

Hooman Bahreini Points 3202

Ce que vous essayez de faire, c'est de construire votre modèle à l'intérieur de la vue (vue personnalisée)... ce n'est pas une bonne pratique... en MVC, les contrôleurs sont responsables de la construction du modèle et de sa transmission à la vue... les vues sont responsables de l'affichage du modèle et doivent avoir le moins de logique possible.


Il semble que ce serait plus efficace si je pouvais écrire chaque URL à dans la réponse au fur et à mesure qu'elles sont ajoutées plutôt que de les garder toutes en mémoire et que et de les écrire en une seule fois.

Pourquoi ? Vous devez garder SitemapItems quelque part dans la mémoire, donc même si vous les écrivez dans la réponse, ils sont toujours conservés en mémoire jusqu'à ce que vous renvoyiez la réponse... et je pense qu'il serait plus efficace de sérialiser toute la liste en XML en une seule fois, par opposition à la sérialisation de chaque SitemapUrl individuellement.


Il y a une solution très élégante à votre question sur ce cours pluralsight :

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

Et vous construisez votre modèle dans le contrôleur, et vous le passez à la vue :

return new SitemapResult(SitemapItems);

Si vous voulez écrire directement dans la réponse, vous pouvez le faire dans le contrôleur :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X