【问题标题】:TFS 2010: Why is it not possible to deserialize a Dictionary<string, object> with XamlWriter.Save when I can use XamlReader for deserializingTFS 2010:当我可以使用 XamlReader 进行反序列化时,为什么无法使用 XamlWriter.Save 反序列化 Dictionary<string, object>
【发布时间】:2012-03-06 10:05:34
【问题描述】:
public static string GetXml(Dictionary<string, object> parameters)
{
    return XamlWriter.Save(parameters);
}

上面的语句返回一个NotSupportedException

奇怪的是我可以使用XamlReader 来序列化字典。

public static Dictionary<string, object> GetParameters(IBuildDetail buildDetail, string buildDefinition)
{
    var tfsProject = buildDetail.BuildDefinition.TeamProject;
    var buildServer = buildDetail.BuildServer;
    var buildDef = buildServer.GetBuildDefinition(tfsProject, buildDefinition);
    using (var stringReader = new StringReader(buildDef.ProcessParameters))
    {
        using (var xmlTextReader = new XmlTextReader(stringReader))
        {
            return (Dictionary<string, object>) XamlReader.Load(xmlTextReader);
        }
    }
}

XML:

<?xml version="1.0" ?>
<Dictionary x:TypeArguments="x:String, x:Object" xmlns="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <mtbwa:BuildSettings ProjectsToBuild="$/XXX/Product/Company.XXX.Common/Company.XXX.Common.Basic/Company.XXX.Common.Basic.csproj" x:Key="BuildSettings">

    <mtbwa:BuildSettings.PlatformConfigurations>

      <mtbwa:PlatformConfigurationList Capacity="4">

        <mtbwa:PlatformConfiguration Configuration="DEMO" Platform="AnyCPU"/>

        <mtbwa:PlatformConfiguration Configuration="Release" Platform="AnyCPU"/>

      </mtbwa:PlatformConfigurationList>

    </mtbwa:BuildSettings.PlatformConfigurations>

  </mtbwa:BuildSettings>

  <mtbwa:TestSpecList Capacity="0" x:Key="TestSpecs"/>

  <x:String x:Key="BuildNumberFormat">
    $(BuildDefinitionName) 6.0.0$(Rev:.r)
  </x:String>

  <mtbwa:CodeAnalysisOption x:Key="RunCodeAnalysis">
    Never
  </mtbwa:CodeAnalysisOption>

  <mtbwa:AgentSettings MaxWaitTime="00:15:00" TagComparison="MatchExactly" Tags="" x:Key="AgentSettings"/>

  <x:Boolean x:Key="AssociateChangesetsAndWorkItems">
    False
  </x:Boolean>

  <x:Boolean x:Key="CreateWorkItem">
    False
  </x:Boolean>

  <x:Boolean x:Key="PerformTestImpactAnalysis">
    False
  </x:Boolean>

  <x:Boolean x:Key="CreateLabel">
    False
  </x:Boolean>

  <x:Boolean x:Key="DisableTests">
    True
  </x:Boolean>

  <x:Boolean x:Key="DoCheckinAssemblyInfoFiles">
    True
  </x:Boolean>

  <x:String x:Key="AssemblyVersionPattern">
    6.0.0.0
  </x:String>

  <x:String x:Key="AssemblyFileVersionPattern">
    6.0.0.B
  </x:String>

  <x:Boolean x:Key="UseObfuscation">
    True
  </x:Boolean>

  <x:String x:Key="ObfuscatorFilePath">
    C:\Program Files (x86)\LogicNP Software\Crypto Obfuscator For .Net 2011 R3\co.exe
  </x:String>

  <x:String x:Key="ObfuscatorProjectFile">
    $/XXX/Product/BuildProcess/Company.XXX.ZZZ.obproj
  </x:String>

  <x:String x:Key="ProjectPath">
    $/XXX/Product/Company.XXX.Common
  </x:String>

</Dictionary>

【问题讨论】:

    标签: c# dictionary xamlwriter


    【解决方案1】:

    我使用 JetBrains dotPeek 了解 Microsoft 如何为 TFS 2010 工作流序列化和反序列化 Dictionary&lt;string, object&gt;

    为了反序列化,他们使用: Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers.DeserializeProcessParameters(string parameterValues)

    他们使用序列化: WorkflowHelpers.SerializeProcessParameters(IDictionary&lt;string, object&gt; parameterValues)

    程序集: Microsoft.TeamFoundation.Build.Workflow.dll

    我最初的问题是我试图在排队构建之前添加 IBuildRequest.ProcessParameters 值。

    private static void SetProcessParametersForSubBuild(IBuildRequest buildRequest, Dictionary<string, object> processParametersForSubBuild, IBuildDefinition buildDefinition)
    {
        var subBuildProcessParameters = WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters);
    
        if (processParametersForSubBuild.Any())
        {
            foreach (var processParameter in processParametersForSubBuild)
            {
                if (subBuildProcessParameters.ContainsKey(processParameter.Key))
                {
                    subBuildProcessParameters[processParameter.Key] = processParameter.Value;
                }
                else
                {
                    subBuildProcessParameters.Add(processParameter.Key, processParameter.Value);
                }
            }
            buildRequest.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(subBuildProcessParameters);
        }
    }
    

    队列构建:

    var queuedBuild = buildServer.QueueBuild(buildRequest);

    【讨论】:

      【解决方案2】:

      是否必须使用 XamlReader/XamlWriter?如果没有 - 看看 DataContractSerializer:

      public static class SerializationExtensions
      {
          public static string Serialize<T>(this T obj)
          {
              var serializer = new DataContractSerializer(obj.GetType());
              using (var writer = new StringWriter())
              using (var stm = new XmlTextWriter(writer))
              {
                  serializer.WriteObject(stm, obj);
                  return writer.ToString();
              }
          }
          public static T Deserialize<T>(this string serialized)
          {
              var serializer = new DataContractSerializer(typeof(T));
              using (var reader = new StringReader(serialized))
              using (var stm = new XmlTextReader(reader))
              {
                  return (T)serializer.ReadObject(stm);
              }
          }
      }
      

      (感谢https://stackoverflow.com/a/5941122/1246870

      【讨论】:

      • 不,这不是必须的,但必须获得相同的架构。使用 DataContractSerializer 会更改架构。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多