通过 C# 创建新的 MediaType(对于 PackageAction)

Create new MediaType via C# (For PackageAction)

我创建了一个需要创建额外 MediaType 的包,因为打包它在包屏幕中不可用。

为了避免这个问题,我开始研究通过 Package Actions 创建一个新的 MediaType。终于开始学习这个快速教程 Umbraco V7 Compatible Packages

添加了一个class(下图),编译(调试模式),复制到Umbraco的/bin/文件夹,然后添加dll作为一个包文件,以及其他所有内容。

然后,在另一个 Umbraco 实例上,从本地包安装它。

问题是:它不工作!

目前我不知道哪里出了问题,所以如果有人有任何建议,欢迎他们。

下面是我创建的class:

using System;
using System.Collections.Generic;
using System.Xml;
using umbraco.interfaces;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;

namespace Social_Media_Channels.Installer
{
    public class AddMediaAction : IPackageAction
    {
        public string Alias()
        {
            return "SocialMediaChannels_AddThemes";
        }

        public bool Execute(string packageName, XmlNode xmlData)
        {
            string STEP = string.Empty;

            if (UmbracoVersion.Current.Major >= 7)
            {
                try
                {
                    #region MediaType
                    STEP = "Adding MediaType";
                    LogHelper.Info(typeof(AddMediaAction), STEP);
                    MediaHelper.AddMediaType();
                    #endregion

                    #region Theme Images
                    STEP = "Adding Media Themes";
                    LogHelper.Info(typeof(AddMediaAction), STEP);

                    #endregion
                    return true;
                }
                catch (Exception ex)
                {
                    var message = string.Concat("Error at install ", Alias(), " package action: " + STEP, ex);
                    LogHelper.Error(typeof(AddMediaAction), message, ex);
                    return false;
                }


            }
            return false;
        }

        public bool Undo(string packageName, XmlNode xmlData)
        {
            if (UmbracoVersion.Current.Major >= 7)
            {
                //MediaType mediaType = new MediaType();
            }
            return true;
        }

        public XmlNode SampleXml()
        {
            var xml = string.Format("<Action runat=\"install\" undo=\"true\" alias=\"{0}\" />", Alias());
            XmlDocument x = new XmlDocument();
            x.LoadXml(xml);
            return x;
        }


    }
}

下面是助手Class:

using System.Collections.Generic;
using Umbraco.Core.Models;

namespace Social_Media_Channels.Installer
{
    public class MediaHelper
    {
        private readonly static string MediaTypeName = "Social Media Theme";

        // LogHelper.Error<TranslationHelper>("Failed to add Opening Soon localization values to language file", ex);
        public static void AddMediaType()
        {
            MediaType mediaType = new MediaType(0);
            mediaType.AllowedAsRoot = true;
            mediaType.Name = MediaTypeName;
            mediaType.Description = "Container for the Social Media Channel Theme Images";
            mediaType.IsContainer = true;

            //Allowed child nodes
            var children = new List<ContentTypeSort>
                {
                    new ContentTypeSort(1031, 0),
                    new ContentTypeSort(1032, 1)
                };

            mediaType.AllowedContentTypes = children;

            //Add properties
            var name = new PropertyType(new DataTypeDefinition(-88, "themeName"));
            name.Name = "Theme Name";
            name.Description = "Name for the theme";

            var url = new PropertyType(new DataTypeDefinition(-88, "themeUrl"));
            url.Name = "Theme Url";
            url.Description = "Url for the original theme";

            var createdBy = new PropertyType(new DataTypeDefinition(-88, "createdBy"));
            createdBy.Name = "Created By";
            createdBy.Description = "Theme Author";

            var createdDate = new PropertyType(new DataTypeDefinition(-41, "createdDate"));
            createdDate.Name = "Created Date";
            createdDate.Description = "Date the Theme was created";

            mediaType.AddPropertyType(name, "Image");
            mediaType.AddPropertyType(url, "Image");
            mediaType.AddPropertyType(createdBy, "Image");
            mediaType.AddPropertyType(createdDate, "Image");
        }

        public static void RemoveMediaType()
        {

        }
    }
}

并且在 Package Actions (Umbraco) 中我添加了以下行

<Action runat="install" undo="true" alias="SocialMediaChannels_AddThemes" />

建议或更正?有人吗?

通过与 DAMP 源代码 (DAMP) 比较,我注意到新的 MediaType class Umbraco.Core.Models.MediaType 缺少 Save()方法,所以无论我怎么测试,它根本不会保存新的媒体类型。

无论如何,同样通过使用 DAMP 的示例(很好的旧 copy/paste),它使用旧程序集并显示消息 'OBSOLETE',想出了新版本的代码,按预期工作。

旧库的代码是什么样的:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Xml;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.datatype;
using umbraco.cms.businesslogic.datatype.controls;
using umbraco.cms.businesslogic.media;
using umbraco.cms.businesslogic.packager.standardPackageActions;
using umbraco.DataLayer;
using umbraco.interfaces;
using umbraco.IO;

namespace SocialMediaChannels
{
    public class AddSocialMediaThemes : IPackageAction
    {
        private readonly static string MediaTypeName = "Social Media Theme";
        private readonly static int LABEL_ID = -92;
        private readonly static int UPLOAD_ID = -90;
        private readonly static int TEXT_ID = -88;
        private readonly static int DATE_ID = -41;
        private readonly static int IMAGE_ID = 1031;
        private readonly static int FOLDER_ID = 1032;

        public IDataType uploadField = new Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"));


        protected static ISqlHelper SqlHelper
        {
            get
            {
                return umbraco.BusinessLogic.Application.SqlHelper;
            }
        }
        public string Alias()
        {
            return "SocialMediaChannels_AddSocialMediaThemes";
        }

        public bool Execute(string packageName, XmlNode xmlData)
        {
            bool flag;

            try
            {
                #region MediaType
                User adminUser = new User(0);

                MediaType theme = CreateMediaType(adminUser, MediaTypeName);

                MediaType folder = MediaType.GetByAlias("Folder");

                int[] folderStructure = folder.AllowedChildContentTypeIDs;
                int newsize = folderStructure.Length + 1;

                Array.Resize(ref folderStructure, newsize);
                folderStructure[newsize - 1] = theme.Id;

                folder.AllowedChildContentTypeIDs = folderStructure;

                MediaType image = MediaType.GetByAlias(MediaTypeName);


                #endregion

                #region Theme Images
                #endregion

                flag = true;
            }
            catch
            {

                flag = false;
            }
            return flag;

        }

        public bool Undo(string packageName, XmlNode xmlData)
        {
            bool flag;
            try
            {
                //remove themes
                flag = true;
            }
            catch
            {
                flag = false;
            }
            return flag;
        }

        public XmlNode SampleXml()
        {
            string sample = string.Format("<Action runat=\"install\" undo=\"true/false\" alias=\"{0}\" ></Action>", Alias());
            return helper.parseStringToXmlNode(sample);
        }
        /// <summary>
        /// Create a Media Type.
        /// </summary>
        /// <param name="adminUser"></param>
        /// <param name="mediaTypeName"></param>
        /// <returns></returns>
        private MediaType CreateMediaType(User adminUser, string mediaTypeName)
        {
            MediaType mediaType = MediaType.MakeNew(adminUser, mediaTypeName);
            int[] typeIds =  { FOLDER_ID, IMAGE_ID };
            mediaType.AllowAtRoot = true;
            mediaType.Text = MediaTypeName;
            mediaType.Description = "Container for the Social Media Channel Theme Images";
            mediaType.IsContainerContentType = true;
            mediaType.AllowedChildContentTypeIDs = typeIds;

            //Add properties
            mediaType.AddPropertyType(new DataTypeDefinition(UPLOAD_ID), "umbracoFile", "Upload image");
            mediaType.AddPropertyType(new DataTypeDefinition(LABEL_ID), "umbracoWidth", "Width");
            mediaType.AddPropertyType(new DataTypeDefinition(LABEL_ID), "umbracoHeight", "Height");
            mediaType.AddPropertyType(new DataTypeDefinition(LABEL_ID), "umbracoBytes", "Size");
            mediaType.AddPropertyType(new DataTypeDefinition(LABEL_ID), "umbracoExtension", "Type");

            mediaType.AddPropertyType(new DataTypeDefinition(TEXT_ID), "themeName", "Name of the Social Channel Theme");
            mediaType.AddPropertyType(new DataTypeDefinition(TEXT_ID), "themeUrl", "Url for the Theme");
            mediaType.AddPropertyType(new DataTypeDefinition(TEXT_ID), "createdBy", "Author of the Theme");
            mediaType.AddPropertyType(new DataTypeDefinition(DATE_ID), "createdDate", "Date the Theme was created");

            mediaType.Text = mediaTypeName;
            mediaType.IconUrl = "mediaPhoto.gif";
            mediaType.Save();

            return mediaType;
        }
    }
}

动作看起来像这样

<Action runat="install" undo="true" alias="SocialMediaChannels_AddSocialMediaThemes" ></Action>

原来我的原始代码有很多问题。经过大量调查,终于让它工作了。

基本上,添加(导致它失败)变成了:

    public static void AddMediaType()
    {
        MediaType mediaType = new MediaType(-1);
        mediaType.AllowedAsRoot = true;
        mediaType.Name = NAME;
        mediaType.Description = "Container for the Social Media Channel Theme Images";
        mediaType.IsContainer = true;
        mediaType.Icon = "icon-picture";
        mediaType.Alias = ALIAS;

        //Allowed child nodes
        var children = new List<ContentTypeSort>
            {
                new ContentTypeSort(FOLDER_ID, 0),
                new ContentTypeSort(IMAGE_ID, 1)
            };

        mediaType.AllowedContentTypes = children;
        DataTypeService dataTypeService = (DataTypeService)ApplicationContext.Current.Services.DataTypeService;


        //Add properties
        var name = new PropertyType(dataTypeService.GetDataTypeDefinitionById(TEXT_ID), "themeName");
        name.Name = "Theme Name";
        name.Description = "Name for the theme";
        name.SortOrder = 0;

        var url = new PropertyType(dataTypeService.GetDataTypeDefinitionById(TEXT_ID), "themeUrl");
        url.Name = "Theme Url";
        url.Description = "Url for the original theme";
        url.SortOrder = 1;

        var createdBy = new PropertyType(dataTypeService.GetDataTypeDefinitionById(TEXT_ID), "createdBy");
        createdBy.Name = "Created By";
        createdBy.Description = "Theme Author";
        createdBy.SortOrder = 2;

        var createdDate = new PropertyType(dataTypeService.GetDataTypeDefinitionById(DATE_ID), "createdDate");
        createdDate.Name = "Created Date";
        createdDate.Description = "Date the Theme was created";
        createdDate.SortOrder = 3;

        mediaType.AddPropertyType(name, "Image");
        mediaType.AddPropertyType(url, "Image");
        mediaType.AddPropertyType(createdBy, "Image");
        mediaType.AddPropertyType(createdDate, "Image");

        ContentTypeService contentTypeService = (ContentTypeService)ApplicationContext.Current.Services.ContentTypeService;
        contentTypeService.Save(mediaType);
    }

现在可以使用了!