Microsoft Dynamics CRM bulk upload web resources (Unofficial WebResourceUtility) and replace entity icons

Keywords: C# SDK xml encoding

Background:

Before last year, we could upload web resources in batches according to the directory WebResourceUtility. Yesterday, we found that it was useless. It was not very convenient to get the source code of WebResourceUtility and change it. I felt that the official code was too redundant and too long, which was not in line with my simple and rude idea. I just accidentally read a code of uploaded resources, so I just wrote a code by myself to upload w according to the directory Tools for EB resources.

Tools:

LinqPad 5

Microsoft Dynamics SDK 9.0

XrmToolBox

The old rules first show the renderings:

Files contained in directory

 

After creating web resources in batch, publish

 

 

Solution add existing resources

 

 

Code

  1 //Microsoft Dynamics CRM Batch upload web Resources (Unofficial WebResourceUtility)Replace Icon
  2 //Corresponding web Resources in mscrm File type of
  3 enum FileTypes
  4 {
  5     HTML = 1,
  6     CSS = 2,
  7     JS = 3,
  8     XML = 4,
  9     PNG = 5,
 10     JPG = 6,
 11     GIF = 7,
 12     XAP = 8,
 13     XSL = 9,
 14     ICO = 10,
 15     SVG = 11,
 16     RESX = 12
 17 }
 18 //Get all files in the directory according to the directory
 19 Dictionary<string, int> GetFilesWithDir(string localPath)
 20 {
 21     Dictionary<string, int> dict = new Dictionary<string, int>();
 22     var typelist = Enum.GetNames(typeof(FileTypes));
 23     var dirs = Directory.GetDirectories(localPath);
 24     //dirs.Dump();
 25     foreach (var dir in dirs)
 26     {
 27         var files = Directory.GetFiles(dir);
 28         //files.Dump();
 29         foreach (var file in files)
 30         {
 31             var index = file.LastIndexOf(".");//.Dump();
 32             if (index == -1) continue;
 33             var filetype = file.Substring(index + 1).ToUpper();
 34             if (typelist.Contains(filetype))
 35             {
 36                 dict.Add(file,
 37                 Enum.Parse(typeof(FileTypes), filetype).GetHashCode()
 38                 );
 39             }
 40 
 41         }
 42     }
 43     return dict;
 44 }
 45 
 46 //Create or update web Resources
 47 Guid CreateOrUpateFile2WebResoulse(IOrganizationService service, string filePath, FileTypes type, string rootPath, string serverPath = "new_/icons/")
 48 {
 49     Stopwatch sw = new Stopwatch();
 50     sw.Start();
 51 
 52     string fileName = filePath.Replace(rootPath, serverPath).Replace("\\", "/");
 53 
 54     var fileContent = File.ReadAllText(filePath);
 55 
 56     fileName = Regex.Replace(fileName, @"[\u4e00-\u9fa5]", "").Replace("//", "/");
 57 
 58     //General text file
 59     var customTypes = new int[] { 1, 2, 3, 4, 11, 12 };
 60 
 61     QueryExpression query = new QueryExpression("webresource")
 62     {
 63         ColumnSet = new ColumnSet(new string[] { "webresourceid" }),
 64         Criteria = new FilterExpression(LogicalOperator.And)
 65     };
 66     query.Criteria.AddCondition("name", ConditionOperator.Equal, new object[] { fileName });
 67     EntityCollection entitys = service.RetrieveMultiple(query);
 68 
 69     Guid entityId;
 70 
 71     Entity entity = new Entity("webresource");
 72     entity["content"] = customTypes.Contains(type.GetHashCode()) ? Convert.ToBase64String(Encoding.UTF8.GetBytes(fileContent.ToString())) : ImgToBase64String(filePath);
 73 
 74     if (entitys.Entities.Count == 0)
 75     {
 76         entity["webresourcetype"] = new OptionSetValue(type.GetHashCode());
 77         entity["displayname"] = fileName;
 78         entity["name"] = fileName;
 79         entity["componentstate"] = new OptionSetValue(0);
 80         entityId = service.Create(entity);
 81     }
 82     else
 83     {
 84         entity = entitys.Entities[0];
 85         service.Update(entity);
 86         entityId = entity.Id;
 87     }
 88     sw.Stop();
 89     Console.WriteLine($"{fileName} Establish/Update succeeded! Time consuming:{sw.ElapsedMilliseconds} Millisecond.");
 90     return entityId;
 91 }
 92 
 93 //Release web Resources
 94 void publishWebResources(List<Guid> ids,IOrganizationService service)
 95 {
 96     Stopwatch sw=new Stopwatch();
 97     sw.Start();
 98     
 99     var sb=new StringBuilder();
100     
101     foreach (var id in ids)
102     {
103         sb.AppendLine($"\r\n<webresource>{id.ToString().ToUpper()}</webresource>\r\n");
104     }
105     XElement element = XElement.Parse("<importexportxml>\r\n<webresources>"+sb.ToString()+"</webresources>\r\n</importexportxml>");
106     PublishXmlRequest request = new PublishXmlRequest();
107     request.ParameterXml = element.ToString();
108     service.Execute(request);
109     sw.Stop();
110     Console.WriteLine($"Batch release! Time consuming:{sw.ElapsedMilliseconds} Millisecond.");
111 
112 }
113 void Main()
114 {    
115     var service = Dynamic365.GetService(Envs.dev);
116     
117     var rootPath = @"D:\Desktop\Icon 20191123\Icon 20191123\";
118     var targetPath = @"new_/dyicon/";
119     var dict=GetFilesWithDir(rootPath).Dump("Files contained in directory");
120     
121     var ids=new List<Guid>();
122     
123     foreach (var kv in dict)
124     {
125         Guid id;
126         try
127         {
128             id=CreateOrUpateFile2WebResoulse(service, kv.Key, (FileTypes)kv.Value, rootPath, targetPath);
129 
130         }
131         catch(Exception ex)
132         {
133             ex.Dump();
134             
135             //Error report and execute again
136             id=CreateOrUpateFile2WebResoulse(service, kv.Key, (FileTypes)kv.Value, rootPath, targetPath);
137         }
138         ids.Add(id);
139     }
140     
141     publishWebResources(ids,service);
142 }

Problem extension:

After the batch upload of web resources, you still need to manually select the web resources to replace the entity icon. Here you can find the iconator plug-in in the plug-in market of xrmtoolbox

 

Final effect drawing of entity modification Icon

Posted by thefury on Sun, 24 Nov 2019 06:17:38 -0800