我正在尝试使用C#构建一个演示型OPC XML DA服务器。开发正在进行中,但我仍然遇到有关阵列的序列化问题。显然,当我尝试将ItemProperty.Value(类型为Object)设置为任何类型的数组但是byte []时,我得到了这个异常:
System.InvalidOperationException:类型< ArrayType>可能不会在这种情况下使用。
以下是触发异常的示例GetProperties()方法的内容:
[WebMethodAttribute()]
[
SoapDocumentMethodAttribute
(
"http://opcfoundation.org/webservices/XMLDA/1.0/GetProperties",
RequestNamespace = "http://opcfoundation.org/webservices/XMLDA/1.0/",
ResponseNamespace = "http://opcfoundation.org/webservices/XMLDA/1.0/",
Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Wrapped
)
]
public override ReplyBase GetProperties
(
[XmlElementAttribute("ItemIDs")] ItemIdentifier[] ItemIDs,
[XmlElementAttribute("PropertyNames")] XmlQualifiedName[] PropertyNames,
[XmlAttributeAttribute()] string LocaleID,
[XmlAttributeAttribute()] string ClientRequestHandle,
[XmlAttributeAttribute()] string ItemPath,
[XmlAttributeAttribute()] [DefaultValueAttribute(false)] bool ReturnAllProperties,
[XmlAttributeAttribute()] [DefaultValueAttribute(false)] bool ReturnPropertyValues,
[XmlAttributeAttribute()] [DefaultValueAttribute(false)] bool ReturnErrorText,
[XmlElementAttribute("PropertyLists")] out PropertyReplyList[] PropertyLists,
[XmlElementAttribute("Errors")] out OPCError[] Errors
)
{
ReplyBase Response = new ReplyBase();
Response.RcvTime = System.DateTime.Now;
Response.RevisedLocaleID = LocaleID;
Response.ClientRequestHandle = ClientRequestHandle;
Errors = null;
PropertyLists = new PropertyReplyList[1] { new PropertyReplyList() };
PropertyLists[0].Properties = new ItemProperty[1] { new ItemProperty() };
PropertyLists[0].Properties[0].Value = new short[2] { 3, 4 };
Response.ReplyTime = System.DateTime.Now;
return Response;
}
完整堆栈跟踪(意大利语)
System.Web.Services.Protocols.SoapException: Impossibile elaborare la richiesta. ---> System.InvalidOperationException: Errore durante la generazione del documento XML. ---> System.InvalidOperationException: Il tipo System.Int16[] può non essere utilizzato in questo contesto.
in System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
in Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write2_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
in Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write16_ItemProperty(String n, String ns, ItemProperty o, Boolean isNullable, Boolean needType)
in Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write19_PropertyReplyList(String n, String ns, PropertyReplyList o, Boolean isNullable, Boolean needType)
in Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write26_GetPropertiesResponse(Object[] p)
in Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer13.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
in System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
--- Fine della traccia dello stack dell'eccezione interna ---
in System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
in System.Web.Services.Protocols.SoapServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
in System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
in System.Web.Services.Protocols.WebServiceHandler.Invoke()
--- Fine della traccia dello stack dell'eccezione interna ---
我已经将wsdl.exe生成的服务框架包含在我的项目中,并且非数组值完全没有问题。我的项目的目标框架是.NET 4.0(但同样的问题发生在3.5)。
我的猜测是该方法与服务框架中的XmlIncludeAttribute()装饰器不兼容。关于如何使其发挥作用的任何线索?
感谢您的时间。
编辑:我尝试将XmlIncludeAttribute(typeof(int []))装饰器添加到GetProperties()方法中(我猜装饰器不可继承),我没有得到例外。但是,客户端无法正确反序列化基础数据。反序列化后从客户端(用VB.NET编写)得到的是XmlNode引用而不是int []。数据存在,但它没有正确地反序列化。
这是预期的行为吗?可能是客户问题?
答案 0 :(得分:0)
在对生成的XML进行更多分析后,我发现客户端需要一个特定的命名空间,即OPC Web服务默认命名空间,以便正确地反序列化数据。我已使用以下装饰器更新了Web服务实现的类定义:
[WebService(Namespace = "http://opcfoundation.org/webservices/XMLDA/1.0/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[XmlInclude(typeof(short[]))]
GetProperties()方法现在正常运行,客户端能够正确地反序列化Int16数组。