2014-02-10 6 views
2

Я пытаюсь выполнить сериализацию контекста исполнения плагина MS CRM 2011 для JSON для его анализа позже (мне нужно найти ошибку, и я предпочел бы, читаемая форма контекстного дампа).Сериализация контекста выполнения плагина MS CRM 2011 для JSON

Но все мои попытки приводит к ошибкам сериализации, как следующее:

Newtonsoft.Json.JsonSerializationException: Error getting value from 'ServiceProvider' on 'Plugin+LocalPluginContext

плагин был сгенерирован Visual Studio надстройки. Код был помещен внутри базового класса Plugin, как это:

internal void Trace(string message) 
{ 
    if (string.IsNullOrWhiteSpace(message) || this.TracingService == null) 
    { 
     return; 
    } 

    if (this.PluginExecutionContext == null) 
    { 
     this.TracingService.Trace(message); 
    } 
    else 
    { 
     this.TracingService.Trace(
      "{0}, Correlation Id: {1}, Initiating User: {2}", 
      message, 
      this.PluginExecutionContext.CorrelationId, 
      this.PluginExecutionContext.InitiatingUserId); 

     var jss = new JsonSerializerSettings(); 
     var dcr = new DefaultContractResolver(); 

     dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic; 
     jss.ContractResolver = dcr; 

     this.TracingService.Trace("Local Context Dump: {0}", JsonConvert.SerializeObject(this, jss)); 
    } 
} 

Я считаю, что этот вопрос является общий подход. LocalContext - очень сложный объект. JSON.NET не может сериализовать некоторые типы. Но я не могу скрыть это ограничение.

Не могли бы вы помочь мне исправить этот подход?

ответ

1

Вы знаете о подходе отладчика плагина? Перепроверьте this article, который описывает, как отлаживать плагины, которые находятся даже в CRM Online.

+0

Да, я, но я хочу, чтобы придумать более удобный модульного тестирования подход, лучше, чем https://crm2011plugintest.codeplex.com/один. Если мне удастся, я поделюсь своими результатами по Киевскому CRM UG. – shytikov

3

Я хотел сделать что-то подобное, но вместо того, чтобы JSON'ing его, я создал собственный метод C#, чтобы скрыть его до строки, и я просто добавлю его в журнал: вот это функция C#, если она помогает ,

protected String GetPluginExecutionInfo(IPluginExecutionContext context) 
{ 
    var lines = new List<String>(); 
    var target = GetTarget<Entity>(context); 

    lines.Add("MessageName: " + context.MessageName); 
    lines.Add("PrimaryEntityName: " + context.PrimaryEntityName); 
    lines.Add("PrimaryEntityId: " + context.PrimaryEntityId); 
    lines.Add("BusinessUnitId: " + context.BusinessUnitId); 
    lines.Add("CorrelationId: " + context.CorrelationId); 
    lines.Add("Depth: " + context.Depth); 
    lines.Add("Has Parent Context: " + (context.ParentContext != null)); 
    lines.Add("InitiatingUserId: " + context.InitiatingUserId); 
    AddParameters(lines, context.InputParameters, "Input Parameters"); 
    lines.Add("IsInTransaction: " + context.IsInTransaction); 
    lines.Add("IsolationMode: " + context.IsolationMode); 
    lines.Add("Mode: " + context.Mode); 
    lines.Add("OperationCreatedOn: " + context.OperationCreatedOn); 
    lines.Add("OperationId: " + context.OperationId); 
    lines.Add("Organization: " + context.OrganizationName + "(" + context.OrganizationId + ")"); 
    AddParameters(lines, context.OutputParameters, "Output Parameters"); 
    AddEntityReference(lines, context.OwningExtension, "OwningExtension"); 
    AddEntityImages(lines, context.PostEntityImages, "Post Entity Images"); 
    AddEntityImages(lines, context.PreEntityImages, "Pre Entity Images"); 
    lines.Add("SecondaryEntityName: " + context.SecondaryEntityName); 
    AddParameters(lines, context.SharedVariables, "Shared Variables"); 
    lines.Add("Stage: " + context.Stage); 
    lines.Add("UserId: " + context.UserId); 

    if (target == null || target.Attributes.Count == 0) 
    { 
     lines.Add("Target: Empty "); 
    } 
    else 
    { 
     lines.Add("* Target " + target.ToEntityReference().GetNameId() + " *"); 
     lines.Add(target.ToStringAttributes(" Target[{0}]: {1}")); 
    } 

    lines.Add("* App Config Values *"); 
    foreach (var key in ConfigurationManager.AppSettings.AllKeys) 
    { 
     lines.Add(" [" + key + "]: " + ConfigurationManager.AppSettings[key]); 
    } 

    return String.Join(Environment.NewLine, lines); 
} 

private static void AddEntityReference(List<string> nameValuePairs, EntityReference entity, string name) 
{ 
    if (entity != null) 
    { 
     nameValuePairs.Add(name + ": " + entity.GetNameId()); 
    } 
} 

private static void AddEntityImages(List<string> nameValuePairs, EntityImageCollection images, string name) 
{ 
    if (images != null && images.Count > 0) 
    { 
     nameValuePairs.Add("** " + name + " **"); 
     foreach (var image in images) 
     { 
      if (image.Value == null || image.Value.Attributes.Count == 0) 
      { 
       nameValuePairs.Add(" Image[" + image.Key + "] " + image.Value + ": Empty"); 
      } 
      else 
      { 
       nameValuePairs.Add("* Image[" + image.Key + "] " + image.Value.ToEntityReference().GetNameId() + " * 
       nameValuePairs.Add(image.Value.ToStringAttributes("  Entity[{0}]: {1}")); 
      } 
     } 
    } 
    else 
    { 
     nameValuePairs.Add(name + ": Empty"); 
    } 
} 

private static void AddParameters(List<string> nameValuePairs, ParameterCollection parameters, string name) 
{ 
    if (parameters != null && parameters.Count > 0) 
    { 
     nameValuePairs.Add("* " + name + " *"); 
     foreach (var param in parameters) 
     { 
      nameValuePairs.Add(" Param[" + param.Key + "]: " + param.Value); 
     } 
    } 
    else 
    { 
     nameValuePairs.Add(name + ": Empty"); 
    } 
} 

public static String ToStringAttributes(this Entity entity, string attributeFormat = "[{0}]: {1}") 
{ 
    return String.Join(Environment.NewLine, entity.Attributes.Select(att => 
     String.Format(attributeFormat, att.Key, GetAttributeValue(att.Value)))); 
} 

private static string GetAttributeValue(object value) 
{ 
    if (value == null) 
    { 
     return "Null"; 
    } 

    var osv = value as OptionSetValue; 
    if (osv != null) 
    { 
     return osv.Value.ToString(); 
    } 

    var entity = value as EntityReference; 
    if (entity != null) 
    { 
     return entity.GetNameId(); 
    } 

    return value.ToString(); 
} 
1

Это работает лучше для меня http://www.crmanswers.net/2015/02/json-and-crm-sandbox-plugins.html

string parameter1 = ""; 
using (MemoryStream memoryStream = new MemoryStream()) 
{ 
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Course)); 
    serializer.WriteObject(memoryStream, course); 
    parameter1 = Encoding.Default.GetString(memoryStream.ToArray()); 
} 
+0

Мне удалось заставить этот код работать, он потребовал от меня добавить атрибут '[DataContract]' к определению класса и '[DataMember]' ко всем его общедоступным полям. – shytikov

Смежные вопросы