Question

I've written the following ImageResizer plugin, But when I change the original image, cached image dose not change unless delete the imagecache folder.

public class MyImageResizerPlugin : IPlugin, IQuerystringPlugin, IVirtualImageProvider
{
    public bool FileExists(string virtualPath, NameValueCollection queryString)
    {
        string fileController = SmartizUrlHelpers.GetUrlHelperInstance().Action("Get", "File");
        return !string.IsNullOrWhiteSpace(fileController) && (virtualPath.StartsWith(fileController, StringComparison.OrdinalIgnoreCase));
    }

    public IVirtualFile GetFile(string virtualPath, NameValueCollection queryString)
    {
        return new GetImageFromVirtualFile(virtualPath, queryString);
    }

    public IEnumerable<string> GetSupportedQuerystringKeys()
    {
        return new[] { "maxwidth", "maxheight", "img" };
    }

    public IPlugin Install(Config c)
    {
        c.Plugins.add_plugin(this);
        return this;
    }

    public bool Uninstall(Config c)
    {
        c.Plugins.remove_plugin(this);
        return true;
    }

    public class GetImageFromVirtualFile : IVirtualFileWithModifiedDate
    {
        public GetImageFromVirtualFile(string virtualPath, NameValueCollection query)
        {
            uint maxwidth, maxheight;

            uint.TryParse(query["maxwidth"], out maxwidth);
            uint.TryParse(query["maxheight"], out maxheight);

            ResizeSettings resizeSettings = new ResizeSettings();

            if (maxwidth > 0) resizeSettings.MaxWidth = (int)maxwidth;
            if (maxheight > 0) resizeSettings.MaxHeight = (int)maxheight;

            this.ResizeSettings = resizeSettings;
            VirtualPath = virtualPath;
        }

        public string VirtualPath { get; private set; }

        protected ResizeSettings ResizeSettings;

        public Stream Open()
        {
            long id;
            string idString = Regex.Replace(VirtualPath, @"\D", "");
            if (!long.TryParse(idString, out id)) return null;
            Attachment attachment = new SmartService().GetAttachmentById(id);
            if (attachment == null) return null;
            MemoryStream memoryStream = new MemoryStream();
            string absoluteFilePath = UploadedPaths.GetAbsolutePath(attachment.Path);
            if (!File.Exists(absoluteFilePath)) throw new HttpException(404, "404 error");
            using (FileStream file = new FileStream(absoluteFilePath, FileMode.Open, FileAccess.Read))
            {
                byte[] bytes = new byte[file.Length];
                file.Read(bytes, 0, (int)file.Length);
                memoryStream.Write(bytes, 0, (int)file.Length);

            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            return memoryStream;
        }

        public DateTime ModifiedDateUTC { get; private set; }
    }
}

I think I doesn't implement IVirtualFileWithModifiedDate correctly. ModifiedDateUTC

Could you please guide me?

Was it helpful?

Solution

You have to provide a different value for ModifiedDateUTC when the underlying file changes. Simply defining the property doesn't solve anything.

As our product is open source, you can take a look at some of the included plugins and how they implement this behavior. Keep in mind that increased latency is a common side effect of checking modified dates on every request, so it's usually better to make blobs immutable (using rewrites if you need to update URLs), or simply change the URL when the contents of an image change (which also ensures CDNs and browsers can handle it).

Keep in mind these plugins are more complex than is generally required, as they implement both the simpler IVirtualFileWithModified date interface as well as the messy VirtualPathProvider system included in ASP.NET.

https://github.com/imazen/resizer/blob/master/Plugins/S3Reader2/S3File.cs

https://github.com/imazen/resizer/blob/master/Plugins/SqlReader/SqlReader.cs

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top