Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SvcUtil生成的c#文件更改WCF服务中的参数类型_C#_Wcf - Fatal编程技术网

SvcUtil生成的c#文件更改WCF服务中的参数类型

SvcUtil生成的c#文件更改WCF服务中的参数类型,c#,wcf,C#,Wcf,我正在尝试创建一个非常简单的web服务,它将接受Xml文件。在我看来,最简单的方法是创建一个接受XmlDocument对象作为参数的方法。我的服务代码如下所示: namespace MercuryWebSvc { public class MercuryWebSvc : IMercuryWebSvc { public void sendData(XmlDocument x) { XDocument xd = x.ToXDo

我正在尝试创建一个非常简单的web服务,它将接受Xml文件。在我看来,最简单的方法是创建一个接受XmlDocument对象作为参数的方法。我的服务代码如下所示:

namespace MercuryWebSvc
{

    public class MercuryWebSvc : IMercuryWebSvc
    {
        public void sendData(XmlDocument x)
        {
            XDocument xd = x.ToXDocument();

            var att = xd.Root.Attributes();
            Console.WriteLine(att.ToString());

        }

    }

    public static class DocumentExtension
    {
        public static XDocument ToXDocument(this XmlDocument xmld)
        {
            using (var xmlReader = new XmlNodeReader(xmld))
            {
                xmlReader.MoveToContent();
                return XDocument.Load(xmlReader);
            }
        }
    }
}
public void sendData(object[] x)
{
    base.Channel.sendData(x);
}
IMercuryWebSvc接口:

[ServiceContract]
public interface IMercuryWebSvc
{
    [OperationContract]
    [ServiceKnownType(typeof(XmlDocument[]))]
    void sendData(XmlDocument x);
}
当我构建项目并使用wsdl文件创建客户端来测试代码时,生成的方法如下所示:

namespace MercuryWebSvc
{

    public class MercuryWebSvc : IMercuryWebSvc
    {
        public void sendData(XmlDocument x)
        {
            XDocument xd = x.ToXDocument();

            var att = xd.Root.Attributes();
            Console.WriteLine(att.ToString());

        }

    }

    public static class DocumentExtension
    {
        public static XDocument ToXDocument(this XmlDocument xmld)
        {
            using (var xmlReader = new XmlNodeReader(xmld))
            {
                xmlReader.MoveToContent();
                return XDocument.Load(xmlReader);
            }
        }
    }
}
public void sendData(object[] x)
{
    base.Channel.sendData(x);
}
出于某种原因,svcutil工具已将接受的参数类型从XmlDocument更改为object[]。这导致我出现以下异常:

System.ServiceModel.CommunicationException was unhandled
  HResult=-2146233087
  Message=There was an error while trying to serialize parameter http://tempuri.org/:x. The InnerException message was 'Type 'System.Xml.XmlDocument' with data contract name 'ArrayOfanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.'.  Please see InnerException for more details.
  Source=mscorlib
  StackTrace:
    Server stack trace: 
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameters(XmlDictionaryWriter writer, PartInfo[] parts, Object[] parameters)
       at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
       at System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
       at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
       at System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)
       at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
       at System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
       at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
       at System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer)
       at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
       at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
       at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]: 
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at IMercuryWebSvc.sendData(Object[] x)
       at MercuryWebSvcClient.sendData(Object[] x) in c:\users\#name\documents\visual studio 2015\Projects\MercuryWebSvc\MercurySvcClient\MercuryWebSvcRef.cs:line 62
       at MercurySvcClient.Program.Main(String[] args) in c:\users\#name\documents\visual studio 2015\Projects\MercuryWebSvc\MercurySvcClient\Program.cs:line 22
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
       HResult=-2146233076
       Message=Type 'System.Xml.XmlDocument' with data contract name 'ArrayOfanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
       Source=System.Runtime.Serialization
       StackTrace:
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
            at WriteArrayOfanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
            at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
            at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
            at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
            at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
       InnerException: 
我读了一些文章,并尝试将KnownTypeAttribute(typeof(XmlDocument[])添加到我的类中,但没有成功。与普通KnownTypeAttribute(typeof(XmlDocument))相同(不是数组)。我需要做什么才能成功地通过此方法传递XmlDocument


编辑:为非数组对象添加了额外的KnownTypeAttribute。

为什么参数是XmlDocument,而ServiceKnownTypeAttribute是数组类型(XmlDocument[])?这看起来很奇怪,我也尝试过使用普通的XmlDocument。同样的结果,您说您尝试了KnownTypeAttribute(typeof(XmlDocument))(注意,no[])是的,这是正确的。我编辑了我的文章来反映这一点。我不熟悉这个工具,但如果我不得不打赌,svcutil就是不能正确处理XmlDocument。见鬼,我甚至不认为XmlDocument可以通过wcf服务发送。。。是的,快速搜索会发现这一点,我建议尝试选择答案的建议(System.Xml.Linq类型更适合使用Xml)。或者,放弃尝试发送/接收复杂类型,并将xml作为字符串发送。