Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
[gelöst] Multiple File Upload via WCF SOAP Endpoint (MTOM) und SoapUI
Wax
myCSharp.de - Member

Avatar #avatar-2276.jpg


Dabei seit:
Beiträge: 745
Herkunft: Dortmund

Themenstarter:

[gelöst] Multiple File Upload via WCF SOAP Endpoint (MTOM) und SoapUI

beantworten | zitieren | melden

Hallo,

Ich habe einen WCF Service der es ermöglicht Dateien hochzuladen. Nun habe ich die Anforderung bekommen, dass die Dateien am besten mittels MTOM Encoding hochgeladen werden sollen und am besten 3 Dateien in einem Request. Der Endpunkt der sich um den Upload kümmert, hat als Binding Parameter das MessageEncoding mit MTOM eingerichtet. Jetzt frage ich mich ob ich im dazugehörigem ServiceContract einfach eine Collection von Streams verwenden kann oder ob es eine Collection von Byte Arrays sein muss, um mehrere MTOM Attachments gleichzeitig entgegennehmen zu können.

Kennt sich da jemand vielleicht mit aus?

Gruß
wax
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Wax am .
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1892
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Zwar habe ich mit MTOM noch nicht gearbeitet, aber die Dateien würde ich als Byte Arrays übertragen.
Je nachdem was du zusätzlich zur Datei übertragen musst, also Daten wie Dateiname etc., würde ich dann eine entsprechende Struktur für die Dateien bauen.
Der Service würde dann einfach eine Liste der Strukturen bekommen und diese dann verarbeiten.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16098

beantworten | zitieren | melden

Prinzipiell ist es theoretisch möglich mehrere Streams anzugeben.
Da aber WCF auf einem Single Stream pro Verbindung basiert, macht das überhaupt kein Sinn.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Normalerweise würde man für den Ansatz eine eigene Stream-Implementierung benutzen, die intern die Sammlung von Streams abgrast. Jedenfalls machen wir das so, ist übersichtlich und wird auch von MS empfohlen. Für den Fall, dass es sich um viele kleine Streams ohne semantischen Zusammenhang handelt, empfiehlt MS dagegen mehrere Requests in einer Session.
Zitat von MSDN
The most common scenario in which such large data content transfers occur are transfers of binary data objects that:

Cannot be easily broken up into a message sequence.

Must be delivered in a timely manner.

Are not available in their entirety when the transfer is initiated.

For data that does not have these constraints, it is typically better to send sequences of messages within the scope of a session than one large message. For more information, see the "Streaming Data" section later in this topic.

LaTino
EDIT: @T-Virus es geht, wenn ich das richtig verstanden habe, um Streamed Transfer. Die Frage, ob man Stream verwendet oder nicht, stellt sich also nicht.

WCF: Large data and streaming
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von LaTino am .
"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)
private Nachricht | Beiträge des Benutzers
Wax
myCSharp.de - Member

Avatar #avatar-2276.jpg


Dabei seit:
Beiträge: 745
Herkunft: Dortmund

Themenstarter:

beantworten | zitieren | melden

Hi zusammen,

danke erstmal für die bisherigen Antworten!

Es muss nicht unbedingt per Stream gemacht werden.

Ich habe jetzt eine Variante, in der mehrere Dateien gleichzeitig geschickt werden könnten.
Hier mal ein Beispiel Aufruf, wie ich ihn aus SoapUI heraus abschicken möchte:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="www.tempuri.org" xmlns:bgp="http://schemas.datacontract.org/2004/07/WSController.Models">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:UploadMultipartDocument>
         <!--Optional:-->
         <tem:multipartDocument>
            <bgp:Parts>
               <bgp:DocumentPart>
                  <bgp:Name>part1.xml</bgp:Name>
                  <bgp:PartData>cid:794981264365</bgp:PartData>
               </bgp:DocumentPart>
               <bgp:DocumentPart>
                  <bgp:Name>part2.xml</bgp:Name>
                  <bgp:PartData>cid:123481264365</bgp:PartData>
               </bgp:DocumentPart>
            </bgp:Parts>
         </tem:multipartDocument>
      </tem:UploadMultipartDocument>
   </soapenv:Body>
</soapenv:Envelope>

In SoapUI wird mir angezeigt, dass die beiden Attachments vom Typ "XOP" sind, also glaube ich erstmal in Ordnung.

Auf Service Seite wirft der XmlMtomReader jetzt die Exception "Ein MIME-Abschnitt mit der Content-ID "cid:794981264365" konnte nicht gefunden werden."

Also entweder schnürt SoapUI das Gesamtpaket nicht korrekt oder ich habe noch ein tieferliegendes Problem.

Gruß
wax
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16098

beantworten | zitieren | melden

Und wie sieht der OperationContract aus.. und TransferMode ist auf Streamed.....?
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
Wax
myCSharp.de - Member

Avatar #avatar-2276.jpg


Dabei seit:
Beiträge: 745
Herkunft: Dortmund

Themenstarter:

beantworten | zitieren | melden

Hier der ServiceContract:


    [ServiceContract(Namespace = "www.tempuri.org")]
    public interface IMultipartDocumentsService
    {
        [OperationContract(Name = "UploadMultipartDocument")]
        void UploadMultipartDocument(MultipartDocument multipartDocument);
    }


Die dazugehörigen Models:


[DataContract]
public class MultipartDocument
{

    [DataMember(IsRequired = true)]
    public string ID
    {
        get;
        set;
    }

    [DataMember(IsRequired = true)]
    public string CreationDate
    {
        get;
        set;
    }


    [DataMember(IsRequired = true)]
    public string Name
    {
        get;
        set;
    }

    [DataMember(IsRequired = true)]
    public Collection<DocumentPart> Parts
    {
        get;
        set;
    }

    public MultipartDocument()
    {
        Parts = new Collection<DocumentPart>();
    }

}



[DataContract]
public class DocumentPart
{

    [DataMember(IsRequired = true)]
    public string Name
    {
        get;
        set;
    }

    [DataMember(IsRequired = true)]
    public byte[] PartData
    {
        get;
        set;
    }

}


Hier das dazugehörige Binding:

<basicHttpBinding>
    <binding name="httpsWithMtom" messageEncoding="Mtom" textEncoding="utf-8">
        <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
        </security>
    </binding>
 </basicHttpBinding>

Gruß
wax
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Wax am .
private Nachricht | Beiträge des Benutzers
Wax
myCSharp.de - Member

Avatar #avatar-2276.jpg


Dabei seit:
Beiträge: 745
Herkunft: Dortmund

Themenstarter:

beantworten | zitieren | melden

Ich habe es hinbekommen und es lag tatsächlich an der Art und Weise wie das SOAP-XML in SoapUI definiert wird. Wenn man in SoapUI ein Attachment hinzufügt, dann wird eine ContentID vergeben.

Und genau diese ContentID musste einfach gleich sein zu dem dazugehörigen PART Eintrag:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="www.tempuri.org" xmlns:bgp="http://schemas.datacontract.org/2004/07/WSController.Models">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:UploadMultipartDocument>
         <!--Optional:-->
         <tem:multipartDocument>
            <bgp:Parts>
               <bgp:DocumentPart>
                  <bgp:Name>part1.xml</bgp:Name>
                  <bgp:PartData>cid:part1.xml</bgp:PartData>
               </bgp:DocumentPart>
               <bgp:DocumentPart>
                  <bgp:Name>part2.xml</bgp:Name>
                  <bgp:PartData>cid:part2.xml</bgp:PartData>
               </bgp:DocumentPart>
            </bgp:Parts>
         </tem:multipartDocument>
      </tem:UploadMultipartDocument>
   </soapenv:Body>
</soapenv:Envelope>

Attachments in SoapUI:
part1.xml mit PART="part1.xml" und ContentID="part1.xml"
part2.xml mit PART="part2.xml" und ContentID="part2.xml"

Für den Request sind außerdem natürlich noch EnableMTOM und ForceMTOM auf true zu setzen.

Gruß
wax
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Wax am .
private Nachricht | Beiträge des Benutzers