简体   繁体   English

Umbraco MediaService / Umbraco MediaItem未保存

[英]Umbraco MediaService / Umbraco MediaItem not saving

I am trying to read an image file from the file system and save it as a MediaItem in Umbraco. 我正在尝试从文件系统读取图像文件,并将其另存为Umbraco中的MediaItem

This is the code I put together: 这是我放在一起的代码:

MemoryStream uploadFile = new MemoryStream();
using (FileStream fs = File.OpenRead(tempFilename))
{
    fs.CopyTo(uploadFile);

    HttpPostedFileBase memoryfile = new MemoryFile(uploadFile, mimetype, Path.GetFileName(src.Value));
    IMedia mediaItem = _mediaService.CreateMedia(Path.GetFileName(src.Value), itNewsMediaParent, "Image");
    mediaItem.SetValue("umbracoFile", memoryfile);
    _mediaService.Save(mediaItem);
    src.Value = library.NiceUrl(mediaItem.Id);
}

Unfortunately, it seems that Umbraco is not able to save the file in the media folder. 不幸的是,似乎Umbraco无法将文件保存在媒体文件夹中。 It does create the node in the Media tree, it sets the correct width, height, and all the rest. 它确实在“媒体”树中创建了节点,并设置了正确的宽度,高度以及所有其他内容。 However it points to /media/1001/my_file_name.jpg . 但是,它指向/media/1001/my_file_name.jpg The media section already contains several images, and the next "ID" that should be used is "1018". 媒体部分已经包含多个图像,下一个应使用的“ ID”为“ 1018”。 Also, if I check inside /media/1001 there is no sign of my_file_name.jpg . 另外,如果我在/media/1001内部检查,则没有my_file_name.jpg

I've also verified that the SaveAs method of memoryfile (which is a HttpPostedFileBase) never gets called. 我还验证了,永远不会调用memoryfile的SaveAs方法(这是一个HttpPostedFileBase)。

Can anyone assist me and point me to the right direction to sort this out? 谁能协助我,并指出正确的方向来解决这个问题?

To Save media, I found this method with MediaService. 为了保存媒体,我在MediaService中找到了此方法。 However, I think it's possible another method more refined 但是,我认为可能还有另一种更完善的方法

    [HttpPost]
    public JsonResult Upload(HttpPostedFileBase file)
    {
        IMedia mimage;

        // Create the media item
        mimage = _mediaService.CreateMedia(file.FileName, <parentId>, Constants.Conventions.MediaTypes.Image);
        mimage.SetValue(Constants.Conventions.Media.File, file);
        _mediaService.Save(mimage);  

        return Json(new { success = true});
    }

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. Media对象对传递给它的某些对象类型的反应不同,在文件的情况下,子类中有一个重写处理HTTPPostedFile,该重写仅在文件发布事件期间创建,但是基类HttpPostedFileBase(这是Umbraco引用的) )可以继承并实现,因此您可以将文件传递到媒体服务,并让Umbraco创建正确的文件路径等。

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. 在下面的示例中,我创建了一个名为FileImportWrapper的新类,该类从HttpPostedFilebase继承,然后继续覆盖所有属性并实现我的版本。

For content type i used the code example presented in this stackoverflow post ( File extensions and MIME Types in .NET ). 对于内容类型,我使用了此stackoverflow帖子中介绍的代码示例( .NET中的文件扩展名和MIME类型 )。

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. 希望对您和其他有相同要求的人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM