Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

How can I access versioning media files i EpiServer CMS 8

Vote:
 

The customer needs to be able to upload new versions of a file and then be able to retrieve all file versions from viewmode.

I’m able to get version information by using "IContentVersionRepository” but I’m only able to load the latest binary.

My Question: How can I load the binary of older file versions?

My code:

[ContentType(GUID = "xxx")]
    public class GenericMedia : MediaData
    {
        public virtual string Description { get; set; }
        public virtual int Filesize { get; set; }
    }

Uploading new version

var fileContent = _contentRepository.Get(assetsFileReference).CreateWritableClone() as GenericMedia;
var blob = _BlobFactory.CreateBlob(fileContent.BinaryDataContainer, fileSufix);

            using (var file = new FileStream(localFileName, FileMode.Open, FileAccess.Read))
            {
                blob.Write(file);
                //Assign to file and publish changes
                fileContent.BinaryData = blob;
                fileContent.Filesize = (int)(file.Length/1024);
                var referenceId = _contentRepository.Save(fileContent, SaveAction.Publish);
                file.Close();
                return referenceId;
            }

Retrieve versions:

private IContentVersionRepository _contentVersionRepository;
private UrlResolver _UrlResolver;


public List GetVersions(ContentReference assetsReference)
{
var versionList = _contentVersionRepository.List(assetsReference);
var list = new List()
foreach (var versionitem in versionList)
{
   Var href = _UrlResolver.GetVirtualPath(versionitem.ContentLink).GetUrl();
   list.add(href);
}
return list;
}

 

#143210
Jan 15, 2016 10:16
Vote:
 

Not sure if you actually can get a unique url for older binarys. I would load the actual content item instead and use the stream from the binary object to show it...

Something like:

//The page you need versions for
ContentReference pageReference = new ContentReference();
//Load all versions
var repository = ServiceLocator.Current.GetInstance<IContentVersionRepository>();
var versions = repository.List(pageReference);
var contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
foreach (var version in versions)
{
//Use contentRepository to grab the media files...
var media = contentRepository.Get<GenericMedia>(version.ContentLink);
var stream = media.BinaryData.OpenRead();
//use stream to render to user...
}

#144356
Feb 11, 2016 13:33
Vote:
 

Thank you Daniel for you response. We ending up getting out the binary as you suggested. We actually implemented a webservice.

Example Url: {BaseUrl}/api/GetFile/1292_1506/filename.jpg

Code example:

[RoutePrefix("api")]
    public class LoadFileController : ApiController
    {
		private IContentRepository _contentRepository;
        private readonly BlobFactory _BlobFactory;
		
		public LoadFileController(IContentRepository contentRepository, BlobFactory blobFactory)
		{
			_contentRepository = contentRepository;
			_BlobFactory  = blobFactory;
		}

        // <param name="fileName">Filename is only needed for the browser to know the filename. </param>
        [Route("GetFile/{imageCode}/{fileName}")]

		public HttpResponseMessage Get(string imageCode, string fileName)
		{
            try
            {
                var contentReference = new ContentReference(imageCode);

                var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);

				
				var mediafile = _contentRepository.Get<MediaData>(contentReference) as MediaData;
				
				var blob = _blobFactory.GetBlob(mediafile.BinaryData.ID)
                Stream stream = blob.OpenRead() as Stream;

                responseMessage.Content = new StreamContent(stream);
                responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(mediafile.MimeType);
                responseMessage.Content.Headers.ContentLength = stream.Length;

                return responseMessage;
            }
            catch (Exception exception)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, exception.Message);
            }
        }
	}
#144552
Edited, Feb 15, 2016 15:54
Vote:
 

Sweet! ...and I do love web api :)

Btw...any reason you call .CreateWritableClone() ? 

I don't see that you update it anywhere?

#144554
Feb 15, 2016 15:58
Vote:
 

Ah. Thanks for you Review. I do not need the .CreateWritableClone(). 

#144562
Feb 15, 2016 16:11
Vote:
 

Then you save some memory and performance. EPiServer did a smart thing there building that model with readonly PageDatas as default to avoid creating a lot of unneccessary objects on heap which is quite expensive.  :)

#144564
Feb 15, 2016 16:21
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.