Pergunta

I have a small intranet service I need to get working where we are submitting test configurations from one domain to another, there is no domain trust that will be set up and since the input template changes data a lot we decided to use Infopath for the scripters/testers in the lab to input their data. I thought, gee, maybe I should do a small WCF server and host it on our IIS server... that should be easy, right?

queue laughing

I tested the connectivity out already using a simple string submit from Infopath to an OperationContract of bool TestInfoPathSubmit(string testString); It works fine both on the dev server and the production server minus the few permission spikes that always seem to happen.

I already have a lot of use out of this ResultDataSet.xsd file we generated from a working xml and using the .NET xsd.exe app so I know it is valid, so I probably can skip linking that code. But here is the rest of it:

interface/contract

[DataContractFormat(Style = OperationFormatStyle.Document)]
[ServiceContract]
public interface IService
{

    [XmlSerializerFormat]
    [OperationContract]
    bool ResultFromInfopath(XmlDocument xdoc);
}

Note: The [XmlSerializerFormat] has been noted to sidestep the issue that XmlDocument cannot be serialized/deserialized in WCF.

Service

public class Service1 : IService
{
    public bool ResultFromInfopath(XmlDocument xdoc)
    {
        try
        {
            var xreader = new XmlNodeReader(xdoc);
            var dataset = new ResultDataSet();
            dataset.ReadXml(xreader);
            Debug.Print("XML has been read in and ready to process");

            return true;
        }
        catch (Exception ex)
        {
            Debug.Print(ex.Message);
            return false;
        }
    }
}

web config

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpBinding" scheme="http" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

Nothing fancy, trying to keep it simple. I created the Infopath document template using the xsd file and linked the Submit to the Web Service and chose the option to submit as a complete XmlDocument, including processing instructions. This is where I made a mistake. Do not include the processing instructions. MSDN - XmlDictionaryReader is the default decoder for the message streams and it won't accept the processing directives embedded in the XmlDocument put in the by InfoPath.

The error you get back is that submit could not be completed:

InfoPath cannot submit the form.
An error occurred while the form was being submitted.
The SOAP response indicates that an error occurred:

Error in deserializing body of request message for operation 'ResultFromInfopath'.
<detail>
    <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <HelpLink i:nil="true"/>
        <InnerException>
            <HelpLink i:nil="true"/>
            <InnerException>
                <HelpLink i:nil="true"/>
                <InnerException i:nil="true"/>
                <Message>
                    Processing instructions (other than the XML declaration) and DTDs are not supported. Line 1, position 485.
                </Message>
                <StackTrace>
                    at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
                    at System.Xml.XmlUTF8TextReader.ReadDeclaration()
                    at System.Xml.XmlUTF8TextReader.Read()
                    at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
                    at System.Xml.XmlLoader.ReadCurrentNode(XmlDocument doc, XmlReader reader)
                    at System.Xml.XmlDocument.ReadNode(XmlReader reader)
                    at System.Xml.Serialization.XmlSerializationReader.ReadXmlNode(Boolean wrapped)
                    at System.Xml.Serialization.XmlSerializationReader.ReadXmlDocument(Boolean wrapped)
                    at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderIService.Read2_ResultFromInfopath()
                    at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer1.Deserialize(XmlSerializationReader reader)
                    at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
                </StackTrace>
                <Type>
                    System.Xml.XmlException
                </Type>
            </InnerException>
            <Message>
                There is an error in XML document (1, 485).
            </Message>
            <StackTrace>
                at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
                at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
                at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, Object[] parameters, Boolean isRequest)
            </StackTrace>
            <Type>
                System.InvalidOperationException
            </Type>
        </InnerException>
        <Message>
            Error in deserializing body of request message for operation 'ResultFromInfopath'.
        </Message>
        <StackTrace>
            at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, Object[] parameters, Boolean isRequest)
            at System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
            at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
            at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
            at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)
            at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
        </StackTrace>
        <Type>
            System.ServiceModel.CommunicationException
        </Type>
    </ExceptionDetail>
</detail>

Answer provided below.

Foi útil?

Solução

Since the XmlDictionaryReader can't read the directives from Infopath, you need to to set up the data submit for Infopath to 'Submit the following data for the selected parameter:' -> 'Field or group'. Select the base node from your XSD as the element for Infopath and let the Data Connection Wizard do the rest.

The XmlDocument xdoc that will be submitted neads to be read into your Dataset and at that point, you are good to go with data.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top