I have a task to upload an image into Sitecore's media library programmatically given the url to the image. How would I make this possible?
4 Answers
There are a couple of steps involved.
- Download the image from the url via a
WebRequest
- Copy the download stream to a
MemoryStream
- Set up a
MediaCreator
- Configure
MediaCreatorOptions
- Create the
MediaItem
Optionally you also need to consider the context Database
and permissions. In this example I am just uploading to "web" and ignoring security. You will probably want to change this a bit.
var webRequest = WebRequest.Create("http://your-domain/logo.png");
using (var webResponse = webRequest.GetResponse())
{
using (var stream = webResponse.GetResponseStream())
{
if (stream != null)
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
var mediaCreator = new MediaCreator();
var options = new MediaCreatorOptions
{
Versioned = false,
IncludeExtensionInItemName = false,
Database = Factory.GetDatabase("web"),
Destination = "/sitecore/media library/Files/logo"
};
using(new SecurityDisabler())
mediaCreator.CreateFromStream(memoryStream, "logo.png", options);
}
}
}
}
Note: Copying the stream to a MemoryStream
is required because the MediaCreator
will issue .Seek()
operations on the stream, something which is not supported on a stream you get from a WebRequest
directly.
You need to download the image and use MediaManager.Creator.CreateFromStream
method.
Sitecore.Resources.Media.MediaManager.Creator.CreateFromStream(ms, fileName, options);
Here is a nice blog post explaining how to create media item programmatically:
Adding a file to the Sitecore Media Library programatically
Scroll to the bottom to see creating media item from stream.
There are many great approaches to this as seen by the list of responses to this question. I would however recommend a solution that is very repeatable and perhaps more automated.
Sitecore PowerShell Extensions
This approach offers a set of PowerShell commands bundled with the SPE Remoting module.
Script
# Source : https://github.com/SitecorePowerShell/Console/tree/master/Modules
Import-Module -Name SPE -Force
$props = @{
Session = (New-ScriptSession -Username "admin" -Password "b" -ConnectionUri "http://console")
Verbose = $true
}
# Upload single file
Get-Item -Path C:\temp\data.xml | Send-RemoteItem @props -RootPath App
Get-Item -Path C:\temp\data.xml | Send-RemoteItem @props -RootPath Package -Destination "\"
Get-Item -Path C:\temp\largeimage.jpg | Send-RemoteItem @props -RootPath App -Destination "\upload\images\"
Get-Item -Path C:\temp\image.png | Send-RemoteItem @props -RootPath Media -Destination "Images/"
Get-Item -Path C:\temp\image.png | Send-RemoteItem @props -RootPath Media -Destination "/sitecore/media library/Images/image2.png"
Get-Item -Path C:\temp\cover.jpg | Send-RemoteItem @props -Destination "{04DAD0FD-DB66-4070-881F-17264CA257E1}"
# Upload single file using full qualified path
Send-RemoteItem @props -Path "C:\temp\data.xml" -Destination "C:\inetpub\wwwroot\Console\Website\upload\data1.xml"
Get-Item -Path C:\temp\data.zip | Send-RemoteItem @props -RootPath App -Destination "\upload"
# Upload multiple files in a flat structure
Get-ChildItem -Path "C:\temp\" -Filter "*.xml" | Send-RemoteItem -Session $session -RootPath Media -Destination "Files/" -Verbose
# Upload multiple files in a compressed zip to maintain directory structure
Get-Item -Path C:\temp\Kittens.zip | Send-RemoteItem @props -RootPath Media -Destination "Images/" -SkipExisting
# Close out the existing session
Stop-ScriptSession -Session $props.Session
Setup
Check out this page in the Gitbook for SPE to see how to get setup and running.
Also note that if you want to update a media stream for an existing media item (the equivalent of an author using detach/attach using the Sitecore UI). Obtain a reference to the MediaItem and then call:
var media = MediaManager.GetMedia(mediaItem);
media.SetStream(stream, "YourFileExtension");
This can be useful if there are content items linking to the media item and you don't want to break existing links but you do want to modify the content of the media item.