Schwierigkeiten bei der Verwendung von WCF für das hochladen von großen Dateien

Gibt es eine Reihe von anderen ähnlichen Fragen auf, SO etwa diese. Leider, viele zu sein scheinen dupes von einander in mancher Hinsicht. Ich hoffe, dass dieser anderen helfen und zur Ruhe setzen andere Fragen.

Mein Projekt erforderlich ist, um 250MB hochladen von Dateien über den IIS in einem backend-WCF-Dienst in IIS gehostet. Ich habe einige unit-tests für die backend-WCF-Dienst in IIS gehostet. Sie sind:

1) Upload 1MB File
2) Upload 5MB File
3) Upload 10MB file
4) Upload 20MB File
5) Upload 200MB File

Rechts von der Fledermaus, es ist wohl klar, dass wir brauchen, um mit irgendeiner Art von streaming oder chunking-Datei übertragen. Ich habe dieses Beispiel.

Das Beispiel beschreibt eine Methode, die verwendet die .NET-Stream-Objekt. Ein Nebeneffekt bei der Verwendung des stream-Objekts, ist, dass müssen Sie verwenden die Message-Verträge. Es ist nicht genug, um den Strom in Ihrer Funktion parameter-Liste. Also tun wir das.

Standardmäßig die web -.config für das WCF service ist ziemlich mager. Und nichts funktioniert:

System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.

Nach langem suchen und Experimentieren, es ist klar, dass "BasicHttpBinding" ist inkompatibel mit dieser Kombination aus Stream-Objekt und die MessageContract. Müssen wir wechseln "WSHttpBinding".

Dazu, die server-web.config wird etwas Komplex unter der Rubrik:

<system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                    <serviceMetadata httpGetEnabled="true"/>
                    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
                </behavior>
                <behavior name="FileServiceBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                    <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" maxConcurrentInstances="500"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        <bindings>
            <wsHttpBinding>
                <binding name="FileServiceBinding" closeTimeout="10:01:00"
                  maxBufferPoolSize="104857600"
                  maxReceivedMessageSize="104857600" openTimeout="10:01:00"
                  receiveTimeout="10:10:00" sendTimeout="10:01:00"
                  messageEncoding="Mtom">
                    <readerQuotas maxDepth="104857600" maxStringContentLength="104857600"
                                  maxArrayLength="104857600" maxBytesPerRead="104857600"
                                  maxNameTableCharCount="104857600" />
                </binding>
            </wsHttpBinding>
        </bindings>
        <services>
            <service behaviorConfiguration="FileServiceBehavior" name="OMS.Service.FileService">
                <endpoint address="" binding="wsHttpBinding" bindingConfiguration="FileServiceBinding" contract="OMS.Service.IFileService"></endpoint>
            </service>
        </services>
    </system.serviceModel>

Ohne mehr Arbeit zu sprechen, 1MB Datei sind nun vorbei mit kein problem.

Um Dateien größer als 4MB zu übergeben, haben Sie zum anpassen einer Einstellung in der web.config im IIS (server-Seite der WCF-service) Dieser Artikel von Microsoft erklärt, was, die Einstellung ist. Zum Beispiel, wenn Sie setzen es auf 8192, dann werden Sie in der Lage, laden Sie die 5MB-Datei, aber nicht alles größer.

<httpRuntime maxRequestLength="8192" />

Ich mir etwas obszön für die Prüfung - 2147483647. Die ersten 4 Dateien übergeben das Tor.

Den 200MB habe nicht die chance bekommen, es zu machen, um das Tor zum nächsten Grund:

System.InsufficientMemoryException: Failed to allocate a managed memory buffer of 279620368 bytes. The amount of available memory may be low. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.

Die Erklärung für dieses problem ist sehr gut beschrieben, durch dieses Plakat.

Denken Sie daran, wie diese. Die 200MB Datei nicht aus dem client. Es muss vollständig geladen werden, bis die vom client verschlüsselt und dann zum server übertragen.

Wenn Sie Visual Studio 2010 zum generieren der proxy-Klassen für den service, es packt ein paar Sachen in Ihre app.config. Für mich sieht es so aus:

<binding 
 name="Binding_IFileService" closeTimeout="00:01:00"
 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
 bypassProxyOnLocal="false" transactionFlow="false" 
 hostNameComparisonMode="StrongWildcard"
 maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Mtom"
 textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
     maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <reliableSession ordered="true" inactivityTimeout="00:10:00"
         enabled="false" />
    <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true" />
    </security>
</binding>

Der Schlüssel ist die security-Modus. Es ist eingestellt "Meldung" standardmäßig. Dieser Wert nahm von was auch immer auf dem server festgelegt ist. Standardmäßig ist das server-Message-level security.

Wenn Sie versuchen, es zu zwingen auf dem server zu sein:

 <security mode="None">

Du diese Fehlermeldung erhalten:

System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at http://localhost:8080/oms/FileService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. ---> System.Net.WebException: The remote server returned an error: (404) Not Found.

(Ich dachte an ein update der client-proxy)

Und so, das ist, wo es steht für mich.... Hilfe!!!

  • Keine Antwort für Sie, aber streaming funktioniert mit BasicHttpBinding und Nachricht Verträge. Ohne zu sehen, Ihre .config auf, dass die Bühne, ich konnte nicht sagen, was die Ursache Ihrer 400 obwohl...
  • Dies ist nicht wirklich eine Antwort, aber wenn ich Probleme mit meiner Bindung und endpoint-Konfigurationen, die ich ein tool verwenden, das in VS2010 zu helfen, machen Sie das XML-ein bisschen weniger verwirrend. Gehen Sie zu "Tools" -> "WCF Service Configuration Editor". Sie können Sie verwenden, um Bearbeiten Sie sowohl Ihre client-und host-Konfiguration. Wie bereits erwähnt, in einer Antwort, beide müssen übereinstimmen, sonst erhalten Sie endpoint nicht gefunden Fehler oder Sicherheit Fehler. BTW, schöne ausführliche Frage!
  • Keine Antwort. Wie kommt man dazu für ein NetTcpBinding? Ich möchte nicht, dass ein dup Frage... irgendwelche Ideen?
InformationsquelleAutor 010110110101 | 2011-11-13
Schreibe einen Kommentar