Laden...

Duplicate Tag in SOAP-Body

Erstellt von impish1234 vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.688 Views
I
impish1234 Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren
Duplicate Tag in SOAP-Body

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

Hinweis von Coffeebean vor 6 Jahren

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?

4.931 Beiträge seit 2008
vor 6 Jahren

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 😉

849 Beiträge seit 2006
vor 6 Jahren

@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.

3.003 Beiträge seit 2006
vor 6 Jahren

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)

I
impish1234 Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

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;
            }
        }
    }

3.003 Beiträge seit 2006
vor 6 Jahren

(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)

I
impish1234 Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

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

849 Beiträge seit 2006
vor 6 Jahren

Hallo impish1234

Das erste <tem:CouponActivationRequest> ist die Methode aus der IService das 2. die Beschreibung der Klasse bzw. des Input Parameter.

I
impish1234 Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

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 👍

3.003 Beiträge seit 2006
vor 6 Jahren

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)

3.003 Beiträge seit 2006
vor 6 Jahren

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)

I
impish1234 Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

@LaTino

Danke nochmals für die Hilfe, hab das ganze mit SVCUTIL aus SDK v8.1.A zum laufen gebracht.

3.003 Beiträge seit 2006
vor 6 Jahren

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)