Hallo,
Ich arbeite zur Zeit an einer Schnittstellen Interface, und hab mich hier für c# wcf entschieden.
Es funktioniert so ziemlich alles, bis auf einen Request den ich zusammen bauen muss, mir aber dies nicht so gelingt wie er aussehen muss. Habe nun nach 2 Tagen googlen keine Ideen mehr und suche nun bei Profis um Hilfe.
Meine Frage ist wie kann ich den ersten <tem:CouponActivationRequest> unterdrücken, bzw. warum gibt es diesen Eintrag im root des bodys (Name der Funktion???).
<body>
<tem:CouponActivationRequest>
<tem:CouponActivationRequest version="1.01.000" requestId="3002" command="activation">
So sieht der Request mit meinem Code aus...... (SOAP UI)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:typ="http://www.loyaltypartner.com/lm/core/couponing/couponactivation/types">
<soapenv:Header/>
<soapenv:Body>
<tem:CouponActivationRequest>
<tem:CouponActivationRequest version="1.01.000" requestId="3002" command="activation">
<typ:couponActivations>
<couponActivation>
<couponIdentifier>100000</couponIdentifier>
<groupingId>6700</groupingId>
<activationChannel>O</activationChannel>
<validUntil>2011-11-12T00:00:00.000+01:00</validUntil>
<cards>
<mainCardNumber>3083421064757539</mainCardNumber>
<cardNumber>?</cardNumber>
</cards>
<targetgroupId>1516</targetgroupId>
<marketingCode>OC32500009</marketingCode>
<barcode>?</barcode>
<validFrom>2011-11-12T00:00:00.000+01:00</validFrom>
<activatedAt>2011-11-12T00:00:00.000+01:00</activatedAt>
</couponActivation>
</typ:couponActivations>
</tem:CouponActivationRequest>
</tem:CouponActivationRequest>
</soapenv:Body>
</soapenv:Envelope>
So sollte das ganze aussehen......
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:couponActivationRequest xmlns:ns2="http://www.loyaltypartner.com/lm/core/couponing/couponactivation/types" requestId="3002" command="activation" version="1.01.000">
<couponActivations>
<couponActivation>
<couponIdentifier>100000</couponIdentifier>
<groupingId>6700</groupingId>
<activationChannel>O</activationChannel>
<validUntil>2011-11-12T00:00:00.000+01:00</validUntil>
<cards>
<mainCardNumber>3083421064757539</mainCardNumber>
</cards>
<targetgroupId>1516</targetgroupId>
<marketingCode>OC32500009</marketingCode>
<validFrom>2011-11-12T00:00:00.000+01:00</validFrom>
<activatedAt>2011-11-12T00:00:00.000+01:00</ activatedAt >
</couponActivation>
</couponActivations>
</ns2:couponActivationRequest>
</S:Body>
</S:Envelope>
Der C# Code dazu...
**IService.cs
using System.ServiceModel;
using MTHPayback_WSDL;
namespace MTHPayback
{
[ServiceContract]
public interface IService
{
[OperationContract]
[XmlSerializerFormat]
CouponActivationResponse CouponActivationRequest(CouponActivationRequest CouponActivationRequest);
}
}
**Service.svc.cs
using System;
using MTHPayback_WSDL;
namespace MTHPayback
{
public class Service : IService
{
public CouponActivationResponse CouponActivationRequest(CouponActivationRequest pbReq)
{
CouponActivationResponse pbResp = new CouponActivationResponse();
pbResp.result = new CouponActivationResult();
pbResp.requestId = pbReq.requestId;
pbResp.version = pbReq.version;
try
{
}
catch (Exception ex)
{
pbResp.result.resultCode = CouponActivationResultCode.InternalError;
}
finally
{
}
return (pbResp);
}
}
}
- knapp 700(!) Zeilen Code entfernt - Coffeebean
Ich habe mal den komplett generierten Code entfernt. Er mag eventuell nützlich sein, aber bitte poste nur die relevanten Stellen. [Hinweis] Wie poste ich richtig?
Dann entferne mal aus dem SOAP XML-Request die beiden Zeilen 4 und 24 (wenn ich mich nicht verzählt habe):
<tem:CouponActivationRequest>
</tem:CouponActivationRequest>
Edit: sorry, falsch verstanden 😉
@Th69 Wenn ich den TS richtig verstanden habe, ist das genau das Problem. Die Zeilen sind drin, obwohl sie nicht da sein dürften.
@ impish1234 kürze mal bitte die klasse CouponActivationRequest auf wesentliche, und poste sie nochmal.
Ist ein Fehler im DataContract. Wo genau, ist schwierig ohne Code 😮).
LaTino
(EDIT: und wieso generierst du den notwendigen Code nicht einfach aus der WSDL und passt ihn dann an?)
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
Danke gleich mal an alle.....
Der ganze Namespace wurde ja von svcutil.exe erstellt - und ich kann diese maximal auf 500 Zeilen reduzieren.
Hier aber mal nur die CouponActivationRequest Klasse daraus
public partial class CouponActivationRequest
{
private CouponActivationRequestCouponActivations couponActivationsField;
private string versionField;
private string requestIdField;
private Command commandField;
private string compensationForRequestField;
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public CouponActivationRequestCouponActivations couponActivations
{
get
{
return this.couponActivationsField;
}
set
{
this.couponActivationsField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public string version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute(DataType = "positiveInteger")]
public string requestId
{
get
{
return this.requestIdField;
}
set
{
this.requestIdField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public Command command
{
get
{
return this.commandField;
}
set
{
this.commandField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute(DataType = "positiveInteger")]
public string compensationForRequest
{
get
{
return this.compensationForRequestField;
}
set
{
this.compensationForRequestField = value;
}
}
}
(Packs bitte noch zwischen zwei CSHARP-Tags, ist dann lesbar, danke!)
Das ist nicht die Klasse, die als Datacontract dann serialisiert wird, sondern die innere Klasse. Wenn man den Code etwas bereinigt (was man IMMER machen sollte, nimm dir die Zeit bitte), sieht sie so aus:
public class CouponActivationRequest
{
[XmlElement(ElementName = "couponActivations", Form = XmlSchemaForm.Unqualified)]
public CouponActivationRequestCouponActivations CouponActivations { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
[XmlAttribute(AttributeName = "requestId", DataType = "positiveInteger")]
public string RequestId { get; set; }
[XmlAttribute(AttributeName = "command")]
public Command Command { get; set; }
[XmlAttribute(AttributeName = "compensationForRequest", DataType = "positiveInteger")]
public string CompensationForRequest { get; set; }
}
Na, ist doch gleich viel ordentlicher. Schau mal, ob du noch eine Klasse hast, die den CouponActivationRequest als Member hat. Strg+Shift+F, Suche nach "private CouponActivationRequest". Das ist dein Übeltäter.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
finde den Übeltäter aber nicht 😭 - such ja auch schon 2 tage nach diesen.....
Hab jetzt mal ein komplett abgespeckte version des ganzen projects gepackt - eventuell helft das mir zu helfen. 😁
wünsche aber allen noch ein nice weekend - und nochmals danke für die hilfe
Hallo impish1234
Das erste <tem:CouponActivationRequest> ist die Methode aus der IService das 2. die Beschreibung der Klasse bzw. des Input Parameter.
Danke für den Hinweis, kann ich das irgendwie anpassen das eventuell der erste <TAG> nicht im BODY angezeigt wird - hab mich da am weekend ein wenig beschäftigt damit aber nichts passendes gefunden?
Ich versteh aber nicht warum der code welcher von svcutil generiert wird (xsd & wsdl), nicht ident ist mit den Ergebnis welches erwartet wird.
auf jeden fall danke an alle für die hilfe 👍
Poste mal bitte die relevanten Teile der WSDL (oder, wenn öffentlich, 'ne Adresse zur vollständigen). Habe noch nie erlebt, dass svcutil etwas anderess tut als das, was die WSDL sagt.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
So, ich hab das mal gerade bei mir ausprobiert. Sieht für mich so aus, als hätte svcutil Schwierigkeiten, den MessageContract mit Attributen entsprechend umzusetzen, und fügt einen - so sieht es für mich aus - überflüssigen Wrapper um den Request hinzu. Wenn du den äußeren MessageContract ersetzt, sollte alles aussehen wie gewünscht. Kann's momentan hier nicht austesten.
Das hier ist der überflüssige Wrapper:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class couponActivationRequest1
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.loyaltypartner.com/lm/core/couponing/couponactivation/types", Order=0)]
public CouponActivationRequest couponActivationRequest;
public couponActivationRequest1()
{
}
public couponActivationRequest1(CouponActivationRequest couponActivationRequest)
{
this.couponActivationRequest = couponActivationRequest;
}
}
Grüße,
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
@LaTino
Danke nochmals für die Hilfe, hab das ganze mit SVCUTIL aus SDK v8.1.A zum laufen gebracht.
Nachtrag noch:
Für solche Fälle ist eine "zweite Meinung" beim erstellen der Proxyklassen immer hilfreich. Ich meine damit: wenn es einem seltsam vorkommt, kann man mit einem anderen Tool noch einmal einen Proxy erstellen und dann vergleichen, wo die Unterschiede sind. Ein derartiges Tool wäre die wsdl.exe - das wäre auch deren einzig verbliebene Daseinsberechtigung 😉.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)