How do you Save/Upload a file to Media using the new MediaService API
Looking at the API docs it says:
It is worth noting that it is also possible to pass a HttpPostedFile, HttpPostedFileBase or HttpPostedFileWrapper to the SetValue method, so it can be used for uploads.
Thats all good and well but looking through other docs all those objects are based around an actual HTTP post and to create those manually is a major ballache.
Is it not possible to open a file, read it into a memory stream and then save it to a byte array and pass in somehow? I have tried this and it doesnt like the array as the SetValue is wanting (string,string).
Got a little futher with this but the API is now throwing an error. Maybe a bug?
I have created a MemoryFile class which inherits from HttpPostedFileBase and all the relevant methods are overwridden etc but when I pass it to the API SetValue method it pukes.
Here is the MemoryFile class:
internal class MemoryFile : HttpPostedFileBase
{
Stream stream;
string contentType;
string fileName;
public MemoryFile(Stream stream, string contentType, string fileName)
{
this.stream = stream;
this.contentType = contentType;
this.fileName = fileName;
}
public override int ContentLength
{
get { return (int)stream.Length; }
}
public override string ContentType
{
get { return contentType; }
}
public override string FileName
{
get { return fileName; }
}
public override Stream InputStream
{
get { return stream; }
}
public override void SaveAs(string filename)
{
using (var file = File.Open(filename, FileMode.CreateNew))
stream.CopyTo(file);
}
}
and here is the code i now have adding to the umbracoFile property - passing in the MemoryFile (also tried the base class as shown below)
However when i debug the memory file it is fully set - it is an object, the stream and fileame and content type etc are all set. Looks a valid object to me. Only thinigs that dont have anything set are the timeout values on the stream but cant see this would be an issue when its a memory stream?
In the stack trace seem to indicate it going off and saving some dynamic types. Ive had a poke around the source but but sure whats going on.
I got this working but changed my code so it actually uses a Post / HttpPostedFileBase. Only problem is the SetValue function seems to have a bug where the media properties Width and Height aren't set. It also doesn't create a folder properly, my new files are always placed in media/0/. I've given up on this method for now.
@James that issue has actually been fixed, so if you upgrade to latest nightly build the files will be placed in the correct folders and the height and width properties will also be set. The issue you are seeing is related to this fixed issue: http://issues.umbraco.org/issue/U4-1689
Dont know if any you can help with an issue I am having. I am creating a new media item using the method Damian has above. In my case I am creating an image. It seems to work fine and creates the media item which can be viewed in umbraco backend. The problem occurs when I view the image in the front end it does not appear.
front end code I use is razor: dynamic mediaItem = new DynamicMedia(id);
When I view this mediaItem in the debuger the niceurl value is not set. If i then go to the umbraco backend and view the media item and save when I then go back to the front end the image now displays and the niceurl field when viewed in the debuger is set.
Is this a bug in the api or am i missing something here??? It seems the api is missing something out.
I think the problem has something to do with the fact im using a console app. just noticed the same thing is happening for pages I am creating using the content api with code I know worked when used from a web app. I think I maybe be missing a config setting possibly will look into it further.
How do you Save/Upload a file to Media using the new MediaService API
Looking at the API docs it says:
It is worth noting that it is also possible to pass a HttpPostedFile, HttpPostedFileBase or HttpPostedFileWrapper to the SetValue method, so it can be used for uploads.
Thats all good and well but looking through other docs all those objects are based around an actual HTTP post and to create those manually is a major ballache.
Is it not possible to open a file, read it into a memory stream and then save it to a byte array and pass in somehow? I have tried this and it doesnt like the array as the SetValue is wanting (string,string).
Here is what i have (ms is the media service)
IMedia newDoc = ms.CreateMedia(doc.Text, folder, "File"); string aName = string.Concat(ASSET_PATH, asset.AssetPath); MemoryStream uploadFile = new MemoryStream(); using (FileStream fs = System.IO.File.OpenRead(aName)) { fs.CopyTo(uploadFile); } newDoc.SetValue("umbracoFile", uploadFile.ToArray()); ms.Save(newDoc);
Got a little futher with this but the API is now throwing an error. Maybe a bug?
I have created a MemoryFile class which inherits from HttpPostedFileBase and all the relevant methods are overwridden etc but when I pass it to the API SetValue method it pukes.
Here is the MemoryFile class:
and here is the code i now have adding to the umbracoFile property - passing in the MemoryFile (also tried the base class as shown below)
The error thrown in object reference not set with the following stack trace:
However when i debug the memory file it is fully set - it is an object, the stream and fileame and content type etc are all set. Looks a valid object to me. Only thinigs that dont have anything set are the timeout values on the stream but cant see this would be an issue when its a memory stream?
In the stack trace seem to indicate it going off and saving some dynamic types. Ive had a poke around the source but but sure whats going on.
Any ideas anyone?
I've tried creating the HttpPostedFile manually and I'm getting the following when invoking the SetValue:
at System.Web.HttpRawUploadedContent.CopyBytes(Int32 offset, Byte[] buffer, Int32 bufferOffset, Int32 length)
at System.Web.HttpInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at System.IO.Stream.CopyTo(Stream destination)
at Umbraco.Core.IO.PhysicalFileSystem.AddFile(String path, Stream stream, Boolean overrideIfExists)
at Umbraco.Core.IO.PhysicalFileSystem.AddFile(String path, Stream stream)
at Umbraco.Core.IO.FileSystemWrapper.AddFile(String path, Stream stream)
at Umbraco.Core.Models.ContentExtensions.SetFileOnContent(IContentBase content, String propertyTypeAlias, String name, Stream fileStream)
at Umbraco.Core.Models.ContentExtensions.SetValue(IContentBase content, String propertyTypeAlias, HttpPostedFile value)
at Umbraco.Core.Models.ContentBase.SetPropertyValue(String propertyTypeAlias, HttpPostedFile value)
at CallSite.Target(Closure , CallSite , Object , String , Object )
at Umbraco.Core.Models.ContentBase.SetValue(String propertyTypeAlias, Object value)
Sigh, might have to just create the folder/save image/thumb manually for now.
Thats what im thinking if we cant get it working in the next day or two.
Shame because it borks the rest of my plans. :(
What was the actual error you received? Thats is just the stack trace.
I have raised this as an issue.
If you are having a problem with this or can recreate please vote it up here and add any comments:
http://issues.umbraco.org/issue/U4-1757
Thanks
I got this working but changed my code so it actually uses a Post / HttpPostedFileBase. Only problem is the SetValue function seems to have a bug where the media properties Width and Height aren't set. It also doesn't create a folder properly, my new files are always placed in media/0/. I've given up on this method for now.
Seems to be when uploading a FIle and not an Image so it may be the Height/Width issue that you reproduced.
@James that issue has actually been fixed, so if you upgrade to latest nightly build the files will be placed in the correct folders and the height and width properties will also be set. The issue you are seeing is related to this fixed issue: http://issues.umbraco.org/issue/U4-1689
http://nightly.umbraco.org/umbraco%206.0.1/UmbracoCms.6.0.1-build.29.zip
As for the main issue in question I have added a comment here: http://issues.umbraco.org/issue/U4-1757#comment=67-5700
- Morten
Thanks Morten.
Issue now fixed in latest nightly build (30)
Dont know if any you can help with an issue I am having. I am creating a new media item using the method Damian has above. In my case I am creating an image. It seems to work fine and creates the media item which can be viewed in umbraco backend. The problem occurs when I view the image in the front end it does not appear.
front end code I use is razor: dynamic mediaItem = new DynamicMedia(id);
When I view this mediaItem in the debuger the niceurl value is not set. If i then go to the umbraco backend and view the media item and save when I then go back to the front end the image now displays and the niceurl field when viewed in the debuger is set.
Is this a bug in the api or am i missing something here??? It seems the api is missing something out.
Try:
mediaItem.GetPropertyValue("umbracoFile");
or
mediaItem.Url
Not sure why the NiceUrl property isn't populated on save, it's most likely a bug.
James thanks for the reply.
I think the problem has something to do with the fact im using a console app. just noticed the same thing is happening for pages I am creating using the content api with code I know worked when used from a web app. I think I maybe be missing a config setting possibly will look into it further.
is working on a reply...