MS CRM 2011 导出Ribbon的定义
原创地址:http://www.cnblogs.com/jfzhu/archive/2013/02/15/2912860.html
转载请注明出处
SDK中有一个Export Ribbon Definations的例子,源代码也可以在sdk\samplecode\cs\client\ribbon\exportribbonxml中找到。SDK中的例子使用了ServerConnection.Configuration类,这个类对EMEA的CRM Online不太好用,总是连接失败。或许对北美的可以使用。
另外SDK中的例子将系统中所有Entity的Ribbon定义全部导出,有一点慢。我在这将该程序简化,使用Microsoft.Xrm.Client.Services.OrganizationService类(参见MS CRM 2011 如何从外部连接CRM),并且将只导出指定的一个Entity Ribbon定义。
简化后的程序如下:
using System; using Microsoft.Xrm.Client.Services; using Microsoft.Xrm.Client; using Microsoft.Crm.Sdk.Messages; using System.ServiceModel; using System.Configuration; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System.IO; using System.IO.Packaging; namespace ExportRibbon { public class ExportRibbon { #region Class Level Members private OrganizationService _orgService; #endregion Class Level Members //Folder name for exported ribbon xml files. public String exportFolder = "ExportedRibbonXml"; public String entityName = "aw_vooraankondiging"; public void Run(String connectionString, bool promptforDelete) { try { // Establish a connection to the organization web service using CrmConnection. Microsoft.Xrm.Client.CrmConnection connection = CrmConnection.Parse(connectionString); // Obtain an organization service proxy. // The using statement assures that the service proxy will be properly disposed. using (_orgService = new OrganizationService(connection)) { //Create export folder for ribbon xml files if not already exist. if (!Directory.Exists(exportFolder)) Directory.CreateDirectory(exportFolder); RetrieveEntityRibbonRequest entRibReq = new RetrieveEntityRibbonRequest() { RibbonLocationFilter = RibbonLocationFilters.All }; entRibReq.EntityName = entityName; RetrieveEntityRibbonResponse entRibResp = (RetrieveEntityRibbonResponse)_orgService.Execute(entRibReq); System.String entityRibbonPath = Path.GetFullPath(exportFolder + "\\" + entityName + "Ribbon.xml"); File.WriteAllBytes(entityRibbonPath, unzipRibbon(entRibResp.CompressedEntityXml)); //Write the path where the file has been saved. Console.WriteLine(entityRibbonPath); } } // Catch any service fault exceptions that Microsoft Dynamics CRM throws. catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>) { // You can handle an exception here or pass it back to the calling method. throw; } } #region Public Methods //<snippetExportRibbonXml2> /// <summary> /// A helper method that decompresses the the Ribbon data returned /// </summary> /// <param name="data">The compressed ribbon data</param> /// <returns></returns> public byte[] unzipRibbon(byte[] data) { System.IO.Packaging.ZipPackage package = null; MemoryStream memStream = null; memStream = new MemoryStream(); memStream.Write(data, 0, data.Length); package = (ZipPackage)ZipPackage.Open(memStream, FileMode.Open); ZipPackagePart part = (ZipPackagePart)package.GetPart(new Uri("/RibbonXml.xml", UriKind.Relative)); using (Stream strm = part.GetStream()) { long len = strm.Length; byte[] buff = new byte[len]; strm.Read(buff, 0, (int)len); return buff; } } #endregion Public Methods #region Private Methods /// <summary> /// Gets web service connection information from the app.config file. /// If there is more than one available, the user is prompted to select /// the desired connection configuration by name. /// </summary> /// <returns>A string containing web service connection configuration information.</returns> private static String GetServiceConfiguration() { var connection = ConfigurationManager.ConnectionStrings["CrmConnection"]; return connection.ConnectionString; } #endregion Private Methods #region Main method /// <summary> /// Standard Main() method used by most SDK samples. /// </summary> /// <param name="args"></param> static public void Main(string[] args) { try { // Obtain connection configuration information for the Microsoft Dynamics // CRM organization web service. String connectionString = GetServiceConfiguration(); if (connectionString != null) { ExportRibbon app = new ExportRibbon(); app.Run(connectionString, true); } } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp); Console.WriteLine("Code: {0}", ex.Detail.ErrorCode); Console.WriteLine("Message: {0}", ex.Detail.Message); Console.WriteLine("Trace: {0}", ex.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == ex.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault"); } catch (System.TimeoutException ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Message: {0}", ex.Message); Console.WriteLine("Stack Trace: {0}", ex.StackTrace); Console.WriteLine("Inner Fault: {0}", null == ex.InnerException.Message ? "Has Inner Fault" : "No Inner Fault"); } catch (System.Exception ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine(ex.Message); // Display the details of the inner exception. if (ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>; if (fe != null) { Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp); Console.WriteLine("Code: {0}", fe.Detail.ErrorCode); Console.WriteLine("Message: {0}", fe.Detail.Message); Console.WriteLine("Trace: {0}", fe.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault"); } } } // Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException, // SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException. finally { Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } } #endregion Main method } }
导出Ribbon定义,要使用到RetrieveEntityRibbonRequest。另外RetrieveEntityRibbonResponse.CompressedEntityXml保存的是压缩(zip)数据,需要使用System.IO.Packaging.ZipPackage将数据解压缩。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构