XAML 无法分析重新承载的WF4设计器中参数的默认值

dfty9e19  于 4个月前  发布在  其他
关注(0)|答案(2)|浏览(31)

当向参数添加默认值时,来自重新承载的设计器(WF 4)的结果会出现问题。其他情况下似乎都可以正常工作。这是(几乎)空工作流的(简化)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来利用Activity。这很好,但由于我没有提供名称,它必须生成一个密钥,在上面的示例中,_b40cActivityXamlServices.Load在处理这些密钥时遇到了一些问题。然而,简单地为ActivityBuilder定义一个名称似乎就可以了。
这仍然不能回答为什么它创建了没有实际名称空间的xmlns:this="clr-namespace:"

bt1cpqcv

bt1cpqcv1#

您的工作流xaml无效。我不知道您从哪里得到它,也不知道它是如何进入这种状态的。
我能说出来是因为

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

字符串
clr样式的命名空间声明无效。它应该为
第一个月

clr-namespace:Some.Namespace;assembly=SomeAssemblyWithSomeNamespace
由于您的声明格式不正确,XamlObjectWriter无法解析thisxml命名空间,以确定您的_b40c类型存在于哪个命名空间/程序集中。此外,这看起来也非常可疑。而且我以前从未见过x:Class设置为null。这也让我感到格式不正确。

oogrdqng

oogrdqng2#

如果我理解得很好-这是 WF Designer 错误。
当我不得不在我的自定义WF设计器中支持InArgument<T>的默认值定义时,我就遇到过这个问题。
故障原因有2个:

  1. x:Class属性中{x:Null}的定义
    1.无效的xmlns:this属性定义
    1.主要问题是参数默认值的定义无效:this:_effe.MyArgument="asd"。参数默认值的定义应该等于:MyXamlClassName.MyArgument="asd"
    例如,如果x:Class定义为x:Class="MyNamespace.MyClass",则参数定义应为this: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


以下是方法定义:

/// <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 Argument declaration with default value. WARNING: when you remove attribute, at this moment you have another item at the place xmlDoc.FirstChild.Attributes[i]
                        //definition of new valid attribute requires: set separately attribute prefix, localName (not "name" - it causes invalid attribute definition) and valid namespace url (in our case it's namespace definition 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);

    });
}


常量定义如下:

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";


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

相关问题