I am trying to write an activity to call a WebService, parse the xml response, and return the results as OutArguement. I am struck trying to access the CodeActivityContext from the OpenReadCompletedEventHandler I have set up to parse the xml. Please see below for what I am trying to accomplish, specifically where I am trying to access the activity context (this.OutputType.Set(context, myCollection)) and let me whether this can be done and how to set up correctly. Many thanks for your help.
[CategoryAttribute("Out Arguments")]
public OutArgument<List<string>> OutputType { get; set; }
protected override void Execute(CodeActivityContext context)
{
Uri svcUri = new Uri(@"http://path/to/webservice");
WebClient svc = new WebClient();
svc.OpenReadCompleted += new OpenReadCompletedEventHandler(svc_OpenReadCompleted);
svc.OpenReadAsync(svcUri);
}
void svc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
Stream responseStream = e.Result;
parametersXml = XDocument.Load(responseStream);
// linq to xml to pull out each of the parameter tags and their descendants
var parameters = from item in parametersXml.Descendants("parameter")
select new myParameter
{
name = item.Element("name").Value,
description = item.Element("description").Value,
defaultValue = item.Element("defaultValue").Value,
optionsType = item.Element("optionsType").Value,
type = item.Element("type").Value,
options = (from ops in item.Descendants("options").Elements()
select new
{
Key = (string)ops.Element("value").Value,
Value = ops.Element("displayAlias") != null
? (string)ops.Element("displayAlias").Value
: ""
}).ToDictionary(pair => pair.Key, pair => pair.Value)
};
foreach (myParameter i in parameters)
{
if (i.name == "DATA_TO_DOWNLOAD")
{
foreach (string optionKey in i.options.Keys)
{
myCollection.Add(optionKey);
}
}
this.OutputType.Set(context, myCollection);
}
}
else
{
}
}
Please read up on the AsyncCodeActivity in WF4. This will allow you to call an APM (Asynchronous Programming Model, i.e. Beginxxx, Endxxx) method pair from an activity without blocking the scheduler thread.
The WebClient class uses the EAP (Event Asynchonous Programming) model so does not have a method pair. You can either use the BeginInvoke EndInvoke pair in a wrapped TPL Task or use HttpWebRequest instead of WebClient.