2

重新托管的设计器 (WF4) 的结果在向参数添加默认值时存在问题。其他所有情况似乎都可以正常工作。这是(几乎)空工作流的(删节)xaml。

<Activity mc:Ignorable="sap" x:Class="{x:Null}" this:_b40c.NewArg="test" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" 
xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" 
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:this="clr-namespace:" xmlns:twc="clr-namespace:Telogis.Workflow.CustomerApi;assembly=Telogis.Workflow.Activities" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <x:Members>
    <x:Property Name="AuthenticationHeader" Type="InArgument(twc:AuthenticationHeader)" />
    <x:Property Name="BaseTdeUri" Type="InArgument(x:Uri)" />
    <x:Property Name="NewArg" Type="InArgument(x:String)" />
  </x:Members>
  <sap:VirtualizedContainerService.HintSize>654,676</sap:VirtualizedContainerService.HintSize>
  <mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
  <Flowchart />
</Activity>

特别是当添加默认值时,对定义进行了以下添加:this:_b40c.NewArg="test"并且xmlns:this="clr-namespace:" xmlns:this="clr-namespace:"无效,因为它不指向任何地方并且无法解析ActivityXamlServices.Load(stream);(它抛出 XamlObjectWriterException: "'Cannot set unknown member '{clr-namespace: }_b40c.NewArg'.' ...) 无论指定的参数类型是什么,这似乎都会发生。

知道是什么原因造成的吗?

更新

我首先使用的ActivityBuilder是活动。这很好,但由于我没有为它提供名称,它必须生成一个密钥,在上面的示例中_b40cActivityXamlServices.Load处理这些密钥有一些问题。然而,简单地定义一个名称ActivityBuilder似乎就可以解决问题。

这仍然不能回答为什么它在xmlns:this="clr-namespace:"没有实际命名空间的情况下创建。

4

2 回答 2

0

您的工作流 xaml 无效。我不确定你从哪里得到它或它是如何进入这种状态的。

我可以这么说,因为

<Activity 
    x:Class="{x:Null}" 
    this:_b40c.NewArg="test"
    xmlns:this="clr-namespace:" 

clr 样式的命名空间声明无效。它应该读

clr-namespace:Some.Namespace.In.The.Current.Assembly

或者

clr-namespace:Some.Namespace;assembly=SomeAssemblyWithSomeNamespace

由于您的声明格式错误,因此 XamlObjectWriter 无法解析_b40cxml 命名空间以确定您的类型存在于哪个命名空间/程序集。此外,这看起来也很可疑。而且我以前从未见过x:Class设置为空。这也让我觉得格式不正确。

于 2012-08-09T17:38:09.447 回答
0

如果我理解得很好 - 这是WF Designer错误。当我不得不InArgument<T>在我的自定义 WF 设计器中支持默认值定义时,我遇到了这个问题。我仍然对缺乏对这个基本程序的支持感到惊讶。

失败的原因有2个:

  1. {x:Null}inx:Class属性的定义
  2. xmlns:this属性定义无效
  3. 主要问题是 Argument 的默认值定义无效:this:_effe.MyArgument="asd"。参数默认值的定义应等于:MyXamlClassName.MyArgument="asd"。例如,如果您的 x:Cass 定义为 x:Class="MyNamespace.MyClass",则参数定义应为:MyClass.MyArgument="asd"。

我通过干预 XAML 保存过程来解决它:调用后 _workflowDesigner.Save(_editedFile);

我添加了这两行:

     #region x:Class and Argument<T> default value issues solution

            await CreateAttributeValue(_editedFile, ConstXClassAttributeName, typeof(App).Namespace + "." + Path.GetFileNameWithoutExtension(_editedFile));
            //should finish first operation before second operation begins to avoid I/O exception
            await CreateAttributeValue(_editedFile, ConstNamespaceAttributeName, ConstXamlClrNamespace + typeof(App).Namespace);
            await RepairArgsAttributes(_editedFile);
                #endregion

This is the methods definition:


  /// <summary>
    /// Reason of using of this method: bug in workflow designer. When you save your xaml file, WF Designer assign "{x:Null}" to x:Class attribute
    /// Bug: In addition, if you want to set default value for your InArgument<T>, it defines attribute "this" (namespace declaration) with empty value. When you try to open your file, designer fails to parse XAML.
    /// </summary>
    /// <param name="editedFile"></param>
    /// <param name="attribteName"></param>
    /// <param name="attributeValueToReplace"></param>
    private static async Task CreateAttributeValue(string editedFile, string attribteName, string attributeValueToReplace)
    {
        XmlDocument xmlDoc = new XmlDocument();
        await Task.Run(() => xmlDoc.Load(editedFile));

        await Task.Run(() =>
        {
            var attributteToReplace = xmlDoc.FirstChild.Attributes?[attribteName];

            if (null != attributteToReplace)
            {
                xmlDoc.FirstChild.Attributes[attribteName].Value = attributeValueToReplace;
                xmlDoc.Save(editedFile);
            }
        });
    }

 /// <summary>
        /// Bug in Workflow designer: workflow designer saves declaration for In/Out Arguments in invalid format. Means, that it is unable to open the same file it saved itself. This method fixes the Arguments declaration in XAML xmlns
        /// </summary>
        /// <param name="editedFile"></param>
        /// <returns></returns>
        private async Task RepairArgsAttributes(string editedFile)
        {
            XmlDocument xmlDoc = new XmlDocument();
            await Task.Run(() => xmlDoc.Load(editedFile));

            await Task.Run(() =>
            {
                for (int i = 0; i < xmlDoc.FirstChild.Attributes.Count; i++)
                {
                    if (xmlDoc.FirstChild.Attributes[i].Name.StartsWith(ConstInvalidArgStarts))
                    {
                        string innvalidAttrName = xmlDoc.FirstChild.Attributes[i].Name;//extraction of full argument declaration in xmlns
                        string[] oldStrings = innvalidAttrName.Split('.');//extraction of arguemnt name string
                        string localName = Path.GetFileNameWithoutExtension(editedFile) + "." + oldStrings[1];//build valid argment declaration without perfix
                        string valueBackup = xmlDoc.FirstChild.Attributes[i].Value;//saving of default value of Arguemnt<T>
                        xmlDoc.FirstChild.Attributes.RemoveNamedItem(xmlDoc.FirstChild.Attributes[i].Name);//removal of invalid Arguemnt declaration with default value. WARNING: when you remove attribue, at this moment you have another item at the place xmlDoc.FirstChild.Attributes[i]
                        //definition of new valid attribute requries: set separelly attribute prefix, localName (not "name" - it causes invalid attribute definition) and valid namespace url (in our case it's namespace deifinition in "this")
                        XmlAttribute attr = xmlDoc.CreateAttribute(ConstArgPrefix, localName, xmlDoc.FirstChild.Attributes[ConstNamespaceAttributeName].Value);
                        attr.Value = valueBackup;
                        xmlDoc.FirstChild.Attributes.InsertBefore(attr, xmlDoc.FirstChild.Attributes[i]);//define new correct Argument declaration attribute at the same place where was invalid attribute. When you put valid attribute at the same place your recover valid order of attributes that was changed while removal of invalid attribute declaration
                    }
                }
                xmlDoc.Save(editedFile);

            });
        }

常量定义为:

 #region Constants
    private const string ConstXClassAttributeName = "x:Class";
    private const string ConstXamlClrNamespace = "clr-namespace:";
    private const string ConstNamespaceAttributeName = "xmlns:this";
    private const string ConstInvalidArgStarts = @"this:_";
    private const string ConstArgPrefix = @"this";

    #endregion

该解决方案也应该可以解决您的问题。

于 2016-03-29T15:39:39.423 回答