Question

Ok, so I have a Visual Studio project and all of the files, images etc that a user uploads get put into the App_Data folder. This worked perfectly fine up until I allowed users to replace images.

I'm having a very specific problem whereby when the image is replaced, because the image is the same file name the image stays the same as the old one. This is fine, this is just because the images are cached. However, you would expect that when I delete the cache and reload the page the new image would be showing.

Even though the correct image is in the App_Data folder, it will display a broken image icon. I thought this was strange so I rebuilt the project and refreshed the page. This then brings through the new image.

My question is, why does this design require a rebuild to properly refresh the images? The images aren't served from App_Data explicitly:

<img src="@Html.ImageAssetUrl(asset.ImageAssetId)" alt="@asset.FileDescription" style="width: 100px;" />


    [OutputCache(Duration = 60 * 60 * 24 * 30, Location = OutputCacheLocation.Any)]
    public ActionResult Image(int assetId, string fileName, string extension, int? cropSizeId)
    {
        ImageAsset asset = imageAssetService.Single(assetId, fileName, extension, true);

        if (asset == null)
            return FileAssetNotFound("Image could not be found");

        string filePath = null;

        if (cropSizeId.HasValue)
        {
            if (asset.ImageCropSizeId.HasValue && asset.ImageCropSizeId.Value == cropSizeId.Value)
            {
                filePath = Server.MapPath(string.Format("~/App_Data/Files/Images/{0}-{1}.{2}", assetId, asset.ImageCropSizeId.Value, asset.Extension));
            }
            else
            {
                foreach (var crop in asset.ImageAssetCrops)
                {
                    if (crop.ImageCropSizeId == cropSizeId.Value)
                    {
                        filePath = Server.MapPath(string.Format("~/App_Data/Files/Images/{0}-{1}.{2}", assetId, crop.ImageCropSizeId, crop.Extension));
                        break;
                    }
                }
            }
        }
        else
        {
            filePath = Server.MapPath(string.Format("~/App_Data/Files/Images/{0}.{1}", assetId, asset.Extension));
        }

        // TODO: Show a better error message
        if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
            return FileAssetNotFound(string.Format("Image file {0} not found on disk", filePath));
        else
            return new FilePathResult(filePath, FileUtil.GetContentType(extension));
    }

Note: I didn't design it this way, so if I could preserve the images being kept in a App_Data -> Files -> Images -> Image structure that would be perfect. I know they shouldn't be in there!!

Was it helpful?

Solution

To always show the latest image add a timestamp to the end of your image url

<img src="folder/image.jpg?ts=<%=DateTime.Now.Ticks%>" />

like this the image wont be cached by the browser, cause the browser thinks its a totally new image even if its the same image or the same image name

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