Created
April 16, 2017 05:39
-
-
Save ace-racer/8d4aa39710b8203c10d589b967104067 to your computer and use it in GitHub Desktop.
Code to update web resource colors on update of theme color in Dynamics 365
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xrm.Sdk; | |
using Microsoft.Xrm.Sdk.Query; | |
using System.Collections.Generic; | |
namespace Contoso.CrmPlugins | |
{ | |
public static class Common | |
{ | |
/// <summary> | |
/// Retrieves the entity by unique values. | |
/// </summary> | |
/// <param name="entityName">Name of the entity.</param> | |
/// <param name="queryColumns">The query columns.</param> | |
/// <param name="requiredColumns">The required columns.</param> | |
/// <param name="service">The service.</param> | |
/// <returns>The entity as per the provided parameters</returns> | |
public static Entity RetrieveEntityByUniqueValues(string entityName, Dictionary<string, object> queryColumns, List<string> requiredColumns, IOrganizationService service) | |
{ | |
if (!string.IsNullOrWhiteSpace(entityName) && queryColumns != null && requiredColumns != null && | |
service != null) | |
{ | |
var query = new QueryExpression(entityName); | |
query.ColumnSet = new ColumnSet(); | |
foreach (var requiredColumn in requiredColumns) | |
{ | |
query.ColumnSet.AddColumn(requiredColumn); | |
} | |
foreach (var queryColumn in queryColumns) | |
{ | |
query.Criteria.AddCondition(queryColumn.Key, ConditionOperator.Equal, queryColumn.Value); | |
} | |
var recordsCollection = service.RetrieveMultiple(query); | |
if (recordsCollection != null && recordsCollection.Entities != null && | |
recordsCollection.Entities.Count > 0) | |
{ | |
return recordsCollection.Entities[0]; | |
} | |
} | |
return null; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xrm.Sdk; | |
using System; | |
using System.Globalization; | |
using System.ServiceModel; | |
using System.Text; | |
namespace Contoso.CrmPlugins | |
{ | |
public class PostThemeUpdate : Plugin | |
{ | |
/// <summary> | |
/// Alias of the image registered for the snapshot of the | |
/// primary entity's attributes before the core platform operation executes. | |
/// The image contains the following attributes: | |
/// Updated fields value | |
/// </summary> | |
private readonly string preImageAlias = "PreImage"; | |
/// <summary> | |
/// The required theme name | |
/// </summary> | |
private readonly string requiredThemeName = "Contoso Theme"; | |
/// <summary> | |
/// The CSS web resource name | |
/// </summary> | |
private readonly string cssWebResourceName = "contoso_bootstrap.css"; | |
public PostThemeUpdate() | |
: base(typeof(PostThemeUpdate)) | |
{ | |
RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(40, "Update", "theme", new Action<LocalPluginContext>(this.ExecuteThemeUpdate))); | |
//// Note : you can register for more events here if this plugin is not specific to an individual entity and message combination. | |
//// You may also need to update your RegisterFile.crmregister plug-in registration file to reflect any change. | |
} | |
protected void ExecuteThemeUpdate(LocalPluginContext localContext) | |
{ | |
if (localContext == null) | |
{ | |
throw new ArgumentNullException("localContext"); | |
} | |
IOrganizationService service = localContext.OrganizationService; | |
IPluginExecutionContext context = localContext.PluginExecutionContext; | |
ITracingService traceService = localContext.TracingService; | |
Entity preImageEntity = (context.PreEntityImages != null && context.PreEntityImages.Contains(this.preImageAlias)) ? context.PreEntityImages[this.preImageAlias] : null; | |
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity && preImageEntity != null) | |
{ | |
Entity targetEntity = (Entity)context.InputParameters["Target"]; | |
try | |
{ | |
var themeName = targetEntity.GetAttributeValue<string>("name"); | |
if (preImageEntity != null) | |
{ | |
if (string.IsNullOrWhiteSpace(themeName)) | |
{ | |
themeName = preImageEntity.GetAttributeValue<string>("name"); | |
} | |
if (string.Compare(themeName, requiredThemeName, StringComparison.CurrentCultureIgnoreCase) == 0) | |
{ | |
// get existing color and get new color as navigation bar color | |
var newThemeColor = targetEntity.GetAttributeValue<string>("navbarbackgroundcolor"); | |
string oldThemeColor = preImageEntity.GetAttributeValue<string>("navbarbackgroundcolor"); | |
if(!string.IsNullOrWhiteSpace(oldThemeColor)) | |
{ | |
var webResourceEntity = ThemeUpdateHelpers.GetWebResourceEntity(service, traceService, cssWebResourceName); | |
if (webResourceEntity != null) | |
{ | |
if (webResourceEntity.Attributes.Contains("content")) | |
{ | |
byte[] existingContentByteArray = Convert.FromBase64String(webResourceEntity.Attributes["content"].ToString()); | |
var existingWebResourceContent = UnicodeEncoding.UTF8.GetString(existingContentByteArray); | |
if (!string.IsNullOrWhiteSpace(existingWebResourceContent)) | |
{ | |
string updatedWebResourceContent = existingWebResourceContent.Replace(oldThemeColor, newThemeColor); | |
byte[] updatedWebResourceContentByteArray = System.Text.Encoding.UTF8.GetBytes(updatedWebResourceContent); | |
var updatedWebResourceContentBase64String = Convert.ToBase64String(updatedWebResourceContentByteArray); | |
webResourceEntity["content"] = updatedWebResourceContentBase64String; | |
service.Update(webResourceEntity); | |
traceService.Trace("Successfully updated"); | |
traceService.Trace("Starting web resource publish"); | |
ThemeUpdateHelpers.PublishWebResource(service, traceService, webResourceEntity.Id); | |
traceService.Trace("Web resource publish completed"); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
catch (FaultException<OrganizationServiceFault> fault) | |
{ | |
localContext.TracingService.Trace(string.Format(CultureInfo.CurrentCulture, "Error in Plugin : Post.{0}Entity Name : {1}{2}Error Message : {3}", Environment.NewLine, context.PrimaryEntityName, Environment.NewLine, fault.Detail.InnerFault != null ? fault.Detail.InnerFault.Message : fault.Detail.Message)); | |
throw new InvalidPluginExecutionException(OperationStatus.Failed, fault.Message); | |
} | |
catch (Exception ex) | |
{ | |
localContext.TracingService.Trace(string.Format(CultureInfo.CurrentCulture, "Error in Plugin : Post.{0}Entity Name : {1}{2}Error Message : {3}", Environment.NewLine, context.PrimaryEntityName, Environment.NewLine, ex.Message)); | |
throw new InvalidPluginExecutionException(OperationStatus.Failed, ex.Message); | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Crm.Sdk.Messages; | |
using Microsoft.Xrm.Sdk; | |
using System; | |
using System.Collections.Generic; | |
namespace Contoso.CrmPlugins.Helpers | |
{ | |
public static class ThemeUpdateHelpers | |
{ | |
/// <summary> | |
/// Gets the web resource entity. | |
/// </summary> | |
/// <param name="orgService">The org service.</param> | |
/// <param name="tracingService">The tracing service.</param> | |
/// <param name="webresourceName">Name of the webresource.</param> | |
/// <returns></returns> | |
public static Entity GetWebResourceEntity(IOrganizationService orgService, ITracingService tracingService, string webresourceName) | |
{ | |
Entity webResourceEntity = null; | |
if(orgService != null && tracingService != null && !string.IsNullOrWhiteSpace(webresourceName)) | |
{ | |
webResourceEntity = Common.RetrieveEntityByUniqueValues("webresource", new Dictionary<string, object>() | |
{ | |
{ "name", webresourceName } | |
}, | |
new List<string>() { "name", "content" }, | |
orgService); | |
} | |
return webResourceEntity; | |
} | |
/// <summary> | |
/// Publishes the web resource. | |
/// </summary> | |
/// <param name="orgService">The org service.</param> | |
/// <param name="tracingService">The tracing service.</param> | |
/// <param name="webresourceName">Name of the webresource.</param> | |
public static void PublishWebResource(IOrganizationService orgService, ITracingService tracingService, Guid webResourceId) | |
{ | |
if(webResourceId != Guid.Empty && orgService != null && tracingService != null) | |
{ | |
PublishXmlRequest publishWebResourceRequest = new PublishXmlRequest | |
{ | |
ParameterXml = string.Format("<importexportxml><webresources><webresource>{0}</webresource></webresources></importexportxml>", webResourceId) | |
}; | |
orgService.Execute(publishWebResourceRequest); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment