I have automatically generated a C# class using the visual studio wsdl.exe tool starting from supplied wsdl and xsd files.
I want to use this client to call a java SOAP service in Italy created by SII (Servizio Informativo integrato).
I am getting this error.
System.Web.Services.Protocols.SoapHeaderException:
'InRequestHandler[pdcInterfacciaServiziSII]:
Il MessaggioSII fornito all'interfaccia Servizi SII non risulta conforme alla struttura standard:
Eccezione SII_EX_ERROR con codice [SII_AU_004] - EccezioneValidazioneProtocollo,
descrizione errore: MessaggioSII ; MessaggioSII without attribute namespace declaration
http://www.acquirenteunico.it/schemas/2010/SII_AU/MessaggioSII'
Translation:
The MessaggioSII supplied to the SII Services Interface does not match with the standard structure:
Exception SII_EX_ERROR with code [SII_AU_004] -
ProtocolValidationException, Error description: MessaggioSII ;
MessaggioSII without attribute namespace declaration
http://www.acquirenteunico.it/schemas/2010/SII_AU/MessaggioSII'
I have also the Java code that calls the same SOAP service and it works perfectly.
This is the relevant part of the C# code automatically generated by the wsdl.exe tool. This code fails with the error written above.
public VerificaInteroperabilitaPdCService() {
this.Url = "http://127.0.0.1:8080/openspcoop2/pdc/PD";
}
public event startCompletedEventHandler startCompleted;
[System.Web.Services.Protocols.SoapRpcMethodAttribute("start", RequestNamespace="http://www.acquirenteunico.it/schemas/2010/SII_AU/VerificaInteroperabilitaPdC", ResponseNamespace="http://www.acquirenteunico.it/schemas/2010/SII_AU/VerificaInteroperabilitaPdC", Use=System.Web.Services.Description.SoapBindingUse.Literal)]
[return: System.Xml.Serialization.XmlElementAttribute("MessaggioSII")]
public StartResponseMessaggioSIIType start(StartMessaggioSIIType MessaggioSII) {
object[] results = this.Invoke("start", new object[] {
MessaggioSII});
return ((StartResponseMessaggioSIIType)(results[0]));
}
public System.IAsyncResult Beginstart(StartMessaggioSIIType MessaggioSII, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("start", new object[] {
MessaggioSII}, callback, asyncState);
}
public StartResponseMessaggioSIIType Endstart(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((StartResponseMessaggioSIIType)(results[0]));
}
The SOAP client should be able to connect to the SOAP service, send a question and get an answer
Related
Edit
I have a problem at deserialising an XML file, containing inner classes (or nested classes).
I have following class diagram:
[XmlRoot(ElementName = "HM")]
public class OwnClass : BaseClass{
...
public OwnClass(){} // default constructor
...
}
I have the following _xmlMessageFormatter declaration (based on System.Messaging):
this._xmlMessageFormatter = new System.Messaging.XmlMessageFormatter();
System.Type[] OwnTypes = new System.Type[30];
OwnTypes[0] = typeof(Baseclasses.OwnClass); /* TR */
...
this._xmlMessageFormatter.TargetTypes = OwnTypes;
Edit: this is what the XML looks like:
<?xml version="1.0"?>
<HM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>124</ID>
<TC>TR</TC>
</HM>
All of this is working fine.
Now I add a new class inside the definition of OwnClass:
[XmlRoot(ElementName = "HM")]
public class OwnClass : BaseClass {
[XmlElement(ElementName = "INS")]
public ClassInside f_Inside;
...
public OwnClass(){} // default constructor
...
public class ClassInside{
...
public class ClassInside(){}
...} // end of ClassInside
} // end of OwnClass
I've also added the corresponding targettype:
OwnTypes [27] = typeof(BaseClasses.OwnClass.ClassInside); // the number of the array is correct.
Edit: the XML file looks now as follows:
<?xml version="1.0"?>
<HM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>125</ID>
<TC>TR</TC>
<TR>
<ID>1</ID>
<CD>MOVE</CD>
</TR>
</HM>
The _xmlMessageFormatter cannot handle the deserialisation, as you can see here:
Source code:
Object temp;
temp = this._xmlMessageFormatter.Read(message);
For getting more information, I've typed ? temp = this._xmlMessageFormatter.Read(message); in the immediate window (I'm working with Visual Studio), this is what I get:
'temp = this._xmlMessageFormatter.Read(message)' threw an exception of type 'System.InvalidOperationException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: {"There was an error reflecting field 'f_Inside'."}
Message: "There was an error reflecting type 'BaseClasses.AnotherClass'."
Source: "System.Xml"
StackTrace: " at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)\r\n at
System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)\r\n at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)\r\n at
System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)\r\n at
System.Messaging.XmlMessageFormatter.CreateTargetSerializerTable()\r\n at
System.Messaging.XmlMessageFormatter.Read(Message message)"
TargetSite: {System.Xml.Serialization.TypeMapping ImportTypeMapping(System.Xml.Serialization.TypeModel,
System.String,
ImportContext,
System.String,
System.Xml.Serialization.XmlAttributes,
Boolean,
Boolean,
System.Xml.Serialization.RecursionLimiter)}
I have two issues with the error message:
It mentions f_Inside. This looks correct, but I have used f_Inside as a general fieldname for all my classes, and the reason I mention this:
It mentions AnotherClass while I have send a message of the form OwnClass.
=> I'm having serious doubts about the correctness of the error message. Is there anybody who knows what I can do now (or how the _xmlFormatter works?)
Edit: added background
All of this is part of a messaging service: one application is sending a message, the other one is receiving it (using the System.Messaging.MessageQueue objects). The serialisation/deserialisation is just a part of it.
Thanks in advance
The problem is solved and it had nothing to do with deserialisation of nested classes:
In one of my classes (AgainAnotherClass), I had following source code:
[XmlElement(ElementName = "SA")]
[XmlElement(ElementName = "SA")]
public string SomeAttribute { get; set; }
(a typical case of Copy/Paste)
The fact that I had two lines with XmlElement caused the problem.
The exception looked as follows:
InnerException: {"There was an error reflecting field 'f_Inside'."}
Message: "There was an error reflecting type '<NameSpace>.AgainOtherClass'."
The InnerException made me believe that there was a problem with the nested class, while the Message spoke about a completely other class. I decided to follow the InnerException.
That was wrong! So, in case of C# exceptions where InnerException and Message contradict each other, first check the Message, then (maybe) the InnerException.
I’m trying to consume a webservice in .NET Core 2.0 by using SOAP. The client for the webservice was generated with the “Connected Service”-feature of Visual Studio.
Now I have the problem, that the webservice needs in the request the (first) line with the encoding-Attribute:
<?xml version="1.0" encoding="utf-8"?>
I’ve tried many different ways to write this line in the output-XML, but nothing works.
First approach:
I added a new endpoint behavior (by implementing IEndpointBehavior) to the client with using a customized message inspector (by implementing IClientMessageInspector). Via debugging I found out, the message object contains the said line. But by writing the outgoing XML to the webservice, the line is missing.
Second approach:
I wrote a customized message encoding binding element with a wsdl export extension (by using MessageEncodingBindingElement & IWsdlExportExtension) . This binding element uses a customized MessageEncoder where the encoding is set explicitly. I added the binding to the generated client.
Here are some .net 4.6 code snippets:
// Binding for the client
TextMessageBindingElement textBindingElement = new TextMessageBindingElement();
textBindingElement.Encoding = "utf-8";
textBindingElement.MessageVersion = MessageVersion.Soap11;
textBindingElement.MediaType = "text/xml";
bindingElements.Add(textBindingElement);
CustomBinding binding = new CustomBinding(bindingElements);
// Customized Message Binding Element for encoding
public class TextMessageBindingElement : MessageEncodingBindingElement,
IWsdlExportExtension {
public override MessageVersion MessageVersion { get; set; }
public string Encoding { get; set; }
...
public override MessageEncoderFactory CreateMessageEncoderFactory() {
return new TextMessageEncoderFactory(MediaType, Encoding, MessageVersion);
}
void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) {
}
void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context) {
TextMessageEncodingBindingElement mebe = new TextMessageEncodingBindingElement();
mebe.MessageVersion = this.msgVersion;
((IWsdlExportExtension) mebe).ExportEndpoint(exporter, context);
}
}
In .NET 4.6 this works, but .NET Core 2.0 doesn’t support IWsdlExportExtension. I’ve searched for alternatives, but haven’t found anything yet.
Please, can anybody help me?
I have an interface contract, and I'm developing a WCF with this contract.
But, there is something wrong because I'm getting this error:
The DataContract element of type ' Contract. Xyt. ObjectWithValXyt'1
[[Contract.Xyt.LayoutXyt, Contract, Version = 2. 5. 0. 0, Culture = neutral, PublicKeyToken = null]]'
You can add to DataContractSet, since the type ' Contract. Xyt. ObjectWithValXyt'1
[[Contract.Xyt.UnitTypeXyt, Contract, Version = 2. 5. 0. 0, Culture = neutral, PublicKeyToken = null]]'
with the same data contract 'ObjectWithVal' in the namespace 'http://myhost.com/Service/2013/09' is already present and the contracts are not equivalent.
And this is a piece of the implementation:
public class Service2 : IAutomationServiceWs
{
public List<Contract.Xyt.UnitTypeInfoXyt> GetUnitTypeInfos()
{
return null;
}
public Contract.Xyt.ObjectWithValXyt<Contract.Xyt.UnitTypeXyt> GetUnitTypeAndValidate(Contract.Xyt.UnitTypeRefXyt unitTypeRef)
{
return null;
}
public List<Contract.Xyt.LayoutInfoXyt> GetLayoutInfos()
{
return null;
}
Why am I getting this error when I run this service on Internet Explorer?
As far as I can tell from the error message, you have 2 different contracts with the same name (ObjectWithVal). You might try to merge them or change the name of one of them.
Try to do a 'Clean' before a 'Build' or debug.
I'm developing a .NET 3.5 webservice using .asmx pages, but the fact that i cant use optional parameters in the GET and POST requests is making me think
in switch my application to WCF. But I didnt understand clearly how it works.
Can you show me how the below code would be if converted to WCF?
[WebService]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class ws :WebService
{
#region WebMethods
//Parameters shoud be optional but it isnt possible in .asmx .NET 3.5
[WebMethod]
public XmlNode GetResult(string param1(=null), string param2(= null))
{
MyClass myClass = new MyClass();
//Get a xml string
string output = myClass.GetXmlString(param1, param2);
//Load this xml
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(output);
//Return this xml
return xmlDocument.DocumentElement;
}
#endregion
}
WSDL cannot describe optional parameters, so it wouldn't matter if you are using ASMX or WCF contracts, the actual semantics of using optional parameters is redundant (they are still classed as required parameters - i.e. like all parameters).
The project I'm currently working on uses Enterprise Libraries V3.1 framework for logging.
I need to take the log file that's generated and archive it off at specific points. The built in Trace Listeners seem to keep the file open in-between logging events. I've set up a custom Trace Listener which will append to a file and close it, so that the file is always shiftable.
It looks like this (minus error handling for clarity):
[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class AlwaysClosedTextFileTraceListener : CustomTraceListener
{
private string logFilePath;
public AlwaysClosedTextFileTraceListener ()
{
logFilePath = #"hardcodedpath\log.txt";
}
public override void Write(string message)
{
using (StreamWriter logFile = File.AppendText(logFilePath))
{
logFile.Write(message);
logFile.Flush();
logFile.Close();
}
}
public override void WriteLine(string message)
{
using (StreamWriter logFile = File.AppendText(logFilePath))
{
logFile.WriteLine(message);
logFile.Flush();
}
}
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
{
if (data is LogEntry && this.Formatter != null)
{
WriteLine(this.Formatter.Format(data as LogEntry));
}
else
{
WriteLine(data.ToString());
}
}
}
This works fine, but I'd much rather be passing in the path as a parameter somehow, rather than hardcoding it.
For fun, I tried adding it to the constructor, to see what happens:
public LogFolderTraceListener(string logFilePath)
{
this.logFilePath = logFilePath;
}
When I do this, I get returned an error message hinting towards what I'm doing wrong:
System.InvalidOperationException : The type 'AlwaysClosedTextFileTraceListener' specified for custom trace listener named 'MyLogFile' does not a default constructor, which is required when no InitData is specified in the configuration.
From here on in, my investigations have very much come to, the opposite of dead ends, infinite probability problems.
I have found this thumbing through the source code for the inbuilt RollingTraceListener
There is a class RollingFlatFileTraceListenerData : TraceListenerData which seems to contain all the settings passed into the constructor
Camped out at the bottom of the file for RollingFlatFileTraceListenerData is the class RollingTraceListenerAssembler : TraceListenerAsssembler which seems to be a factory
There is another class SystemDiagnosticsTraceListenerNode : TraceListenerNode which seems to make the Data class presentable to the configuration application
My question is this: how do I create a CustomTraceListener with a configurable parameter of path?
The CustomTraceListener derives from TraceListener, this has a StringDictionary called Attributes.
This will contain all the attributes in the configuration line for your TraceListener and can be gotten out by name, eg.
string logFileName= Attributes["fileName"]
I suspect that perhaps the Enterprise Application Blocks although (probably) wonderful, seem unnecessarily complicated and ultimately more trouble than their worth for this kind of customisation.
the problem is typical microsoft .. (add your own adjectives here) ..
1) when you add a custom trace listener, the 'raw' app.config statement added is:
name="Custom Trace Listener" initializeData="" formatter="Text Formatter" />
2) notice the 'initializeData' - this is what the cryptic error message is calling'InitData'.
3) So what its all saying is that you need to have a constructor that accepts initialization data - in vb parlance:
sub new (byval initstuff as string)
4) OR remove the 'initializeData=""' and have a default constructor:
sub new()
I suspect the P&P folks live in a bubble.
riix.
For what it is worth this is how I implemented it. In my this.buildCurrPath() I can read from a config file or in this case I just get the "launch pad" for the web app. But it works fine for me. I have not put it into any production code yet, but it should go out soon.
[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class CustomListener: CustomTraceListener
{
#region Fields (3)
private int logSize;
StreamWriter sw;
#endregion Fields
#region Constructors (1)
public CustomListener ():base()
{
string startPath = this.buildCurrPath();
sw = new StreamWriter(startPath + "\\Logs\\test.log");
sw.AutoFlush = true;
}
I have just had the same issue (except with Enterprise Library v4.1).
The solution I've found is to remove the default constructor and the only have a constructor with a string parameter for the filename i.e.
public AlwaysClosedTextFileTraceListener (string pathParameter)
{
logFilePath = pathParameter;
}
Then in the app.config put your path in the initializeData parameter
<add ... initializeData="C:\Logs\myLog.log" />
Whilst this isn't recognised by the Entriprise Library configuration editor and isn't as neat as it could be, it works as long as there is only one parameter.
If someone works out how to do it properly, please post and let us know - it's not supposed to be this difficult, surely.