The Media object reacts differently for some object types pass to it, in the case of files there is an override in the child classes that handles an HTTPPostedFile which is only created during a file post event however the base class HttpPostedFileBase (which is what Umbraco references) can by inherited and implemented so you can pass files to the media service and have Umbraco create the right file path etc.
In the example below I have created a new class called FileImportWrapper that inherits from HttpPostedFilebase I then proceed to override all properties and implement my version of them.
For content type i used the code example presented in this stackoverflow post (File extensions and MIME Types in .NET).
See the example code below.
Class Code
public sealed class FileImportWrapper : HttpPostedFileBase
{
private FileInfo fileInfo;
public FileImportWrapper(string filePath)
{
this.fileInfo = new FileInfo(filePath);
}
public override int ContentLength
{
get
{
return (int)this.fileInfo.Length;
}
}
public override string ContentType
{
get
{
return MimeExtensionHelper.GetMimeType(this.fileInfo.Name);
}
}
public override string FileName
{
get
{
return this.fileInfo.FullName;
}
}
public override System.IO.Stream InputStream
{
get
{
return this.fileInfo.OpenRead();
}
}
public static class MimeExtensionHelper
{
static object locker = new object();
static object mimeMapping;
static MethodInfo getMimeMappingMethodInfo;
static MimeExtensionHelper()
{
Type mimeMappingType = Assembly.GetAssembly(typeof(HttpRuntime)).GetType("System.Web.MimeMapping");
if (mimeMappingType == null)
throw new SystemException("Couldnt find MimeMapping type");
ConstructorInfo constructorInfo = mimeMappingType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
if (constructorInfo == null)
throw new SystemException("Couldnt find default constructor for MimeMapping");
mimeMapping = constructorInfo.Invoke(null);
if (mimeMapping == null)
throw new SystemException("Couldnt find MimeMapping");
getMimeMappingMethodInfo = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic);
if (getMimeMappingMethodInfo == null)
throw new SystemException("Couldnt find GetMimeMapping method");
if (getMimeMappingMethodInfo.ReturnType != typeof(string))
throw new SystemException("GetMimeMapping method has invalid return type");
if (getMimeMappingMethodInfo.GetParameters().Length != 1 && getMimeMappingMethodInfo.GetParameters()[0].ParameterType != typeof(string))
throw new SystemException("GetMimeMapping method has invalid parameters");
}
public static string GetMimeType(string filename)
{
lock (locker)
return (string)getMimeMappingMethodInfo.Invoke(mimeMapping, new object[] { filename });
}
}
}
Usage Code
IMedia media = ApplicationContext.Current.Services.MediaService.CreateMedia("image test 1", -1, Constants.Conventions.MediaTypes.Image);
this.mediaService.Save(media); // called it before so it creates a media id
FileImportWrapper file = new FileImportWrapper(IOHelper.MapPath("~/App_Data/image.png"));
media.SetValue(Constants.Conventions.Media.File, file);
ApplicationContext.Current.Services.MediaService.Save(media);
I hope this helps you and others with the same requirement.