MVC - Как разместить случайные изображения из папки на главной странице - PullRequest
2 голосов
/ 10 апреля 2009

У меня есть приложение MVC, и я хочу в верхней части главной страницы есть серия случайных изображений из папки.

Для этого мне нужно написать код, но не куда писать код ?? Это должно быть сделано в одном месте.

Я, вероятно, просто установлю изображения в начале сессии поэтому они кэшируются браузером и улучшают производительность сайта.

Malcolm

Ответы [ 4 ]

3 голосов
/ 10 апреля 2009

Кэширование - это ключ

Как уже говорили другие, вы должны использовать кэширование, так как вы выполняете повторяющиеся операции дискового ввода-вывода для данных, которые меняются не часто.

Мой пример создает и кэширует List<T> путей к файлам изображений, которые вам понадобятся для каждого последующего запроса. System.Web.Caching идеально подходит для этого, потому что вы можете создать объект CacheDependency непосредственно в вашем каталоге изображений - если файл будет изменен или добавлен, ваш кеш автоматически аннулируется. Затем он воссоздается при следующем запросе.

Избежание дубликатов с HashSet<T>

Могу поспорить, что вы не хотите, чтобы в заголовке появлялись две одинаковые картинки!

Рандомизация с использованием Random.Next не исключает ранее сгенерированные дубликаты. Я использовал HashSet<T> в качестве уникального рандомизатора для бедняков, поскольку HashSet<T> позволит вам только добавлять уникальные значения.

Модель

Эта операция должна быть частью вашей модели в MVC. Вы измените его так, чтобы он соответствовал другим классам извлечения данных, как вам будет удобно.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Caching;

public class RandomImage
{
    public static string[] GetImages(string folder, int count)
    {
        HttpContext context = HttpContext.Current;
        string virtualFolderPath = string.Format("/content/{0}/", folder);
        string absoluteFolderPath = context.Server.MapPath(virtualFolderPath);

        Cache cache = context.Cache;
        var images = cache[folder + "_images"] as List<string>;

        // cache string array if it does not exist
        if (images == null)
        {
            var di = new DirectoryInfo(absoluteFolderPath);
            images = (from fi in di.GetFiles()
                            where fi.Extension.ToLower() == ".jpg" || fi.Extension.ToLower() == ".gif"
                            select string.Format("{0}{1}", virtualFolderPath, fi.Name))
                            .ToList();


            // create cach dependency on image randomFolderName
            cache.Insert(folder + "_images", images, new CacheDependency(absoluteFolderPath));
        }

        Random random = new Random();
        var imageSet = new HashSet<string>();
        if (count > images.Count())
        {
            throw new ArgumentOutOfRangeException("count");
        }

        while (imageSet.Count() < count)
        {
            //using an hashset will ensure a random set with unique values.
            imageSet.Add(images[random.Next(count)]);
        }

        return imageSet.ToArray();
    }
}

Контроллер

Доступ к методу в вашем контроллере что-то вроде ....

string[] images = Models.RandomImage.GetImages("myPictures", 4);
2 голосов
/ 10 апреля 2009

Ну, чтобы получить изображения:

string[] get_images(string folder) {
     string[] files = Directory.GetFiles(folder, "*.jpg"/* or whatever */);
     List<string> rand = new List<string>();
     Random r = new Random();
     for ( int i = 0; i < numImages; i++ ) {
         rand.Add(Path.GetFileName(files[r.Next(files.Length-1)]));
     }
     return rand.ToArray();
}

А потом на главной странице:

<% PrintImages(); %>

Где PrintImages ():

string[] img = get_images(Server.MapPath("~/Content/RandomImages"));
foreach (string i in img) { Response.Write("<img src=\"/Content/RandomImages/"+i+"\" />"); }

Это грубое решение, и кэширование было бы хорошо - это действительно сломало бы диск.

2 голосов
/ 10 апреля 2009

Напишите вспомогательную функцию, которая бы получала случайное имя файла из массива имен файлов, который генерируется при запуске приложения.

0 голосов
/ 10 апреля 2009

Я бы хотел убедиться, что простое чтение каталога каждый раз и генерация имен файлов является настоящим узким местом, прежде чем я сделаю что-нибудь более сложное. Это, конечно, менее эффективно, но код, возможно, проще. Если это не узкое место, то действие контроллера, ответственное за рендеринг представления, является правильным местом для кода. Обратите внимание, что вам нужно отключить кэширование вывода для действия (если оно еще не выполнено), если вы хотите, чтобы изображение каждый раз менялось.

Если окажется, что чтение имен файлов и построение ссылок действительно является узким местом - это может занять гораздо меньше времени, чем чтение самого файла - И файлы в каталоге могут измениться во время работы приложения, тогда создание коллекции из них и сохранение их в сеансе при входе в систему - разумный способ справиться с этим. Предостережение заключается в том, что, если приложение также отвечает за загрузку изображений (чтобы оно знало, когда они изменяются), вы можете загрузить их при запуске приложения и сохранить их в глобальном экземпляре, который обновляется приложением, поскольку изображения загружено (или удалено).

Если у вас есть коллекция изображений (путем чтения каждый раз из сеанса или глобального экземпляра), используйте генератор случайных чисел, чтобы выбрать изображение, которое вы хотите отобразить, или набор, который вы хотите повернуть, используя что-то вроде плагина jQuery Cycle, передайте его (их) в представление и сделайте так, чтобы он отображал теги изображений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...