TFS 2010: Why Can't I Deserialize the <string, object> Dictionary Using XamlWriter.Save, When Can I Use XamlReader to Deserialize

public static string GetXml(Dictionary<string, object> parameters) { return XamlWriter.Save(parameters); } 

The above statement returns a NotSupportedException .

It is strange that I can use XamlReader to serialize a dictionary.

 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> 
+7
source share
2 answers

I used JetBrains dotPeek to find out how Microsoft serializes and deserializes Dictionary<string, object> for TFS 2010 Workflow.

For deserialization, they use: Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers.DeserializeProcessParameters(string parameterValues)

For serialization, they use: WorkflowHelpers.SerializeProcessParameters(IDictionary<string, object> parameterValues)

Build: Microsoft.TeamFoundation.Build.Workflow.dll

My initial problem was that I was trying to add IBuildRequest.ProcessParameters values โ€‹โ€‹before the build queue.

 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); } } 

Queue Build:

var queuedBuild = buildServer.QueueBuild (buildRequest);

+2
source

Do I need to use XamlReader / XamlWriter? If not, take a look at the 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); } } } 

(credits https://stackoverflow.com/a/168248/ )

+1
source

All Articles