2016-05-14 6 views
0

Ich habe eine Anwendung, die große Dateien erhalten soll, deshalb verwende ich einen stream Parameter.Empfangen Sie große Dateien über WCF-Dienst

Servicevertrag:

[ServiceContract] 
public interface IFile 
{ 
    [OperationContract] 
    [WebInvoke(Method = "POST", UriTemplate = "/Upload?fileName={fileName}&requestType={requestType}", ResponseFormat = WebMessageFormat.Json)] 
    FileMetadata Upload(string fileName, RequestType requestType, Stream stream); 
} 

Umsetzung:

public FileMetadata Upload(string fileName, RequestType requestType, Stream stream) 
{ 
    var contract = GetContract(fileName, requestType, stream); 
    ... 
} 

private static FileUploadRequest GetContract(string fileName, RequestType requestType, Stream content) 
{ 
    var ms = new MemoryStream(); 
    content.CopyTo(ms); 
    return new FileUploadRequest 
    { 
     Filename = fileName, 
     RequestType = requestType, 
     Content = ms.ToArray() 
    }; 
} 

Aber mit Strom ich einen Müll info (Grenze usw.) erhalten, Probe übergebene XML ist:

--a288ea6c-376a-4c7e-9680-39199e34082c 
Content-Disposition: form-data 

<Doc> ... rest of XML 

Wie kann ich einen Stream selbst übertragen? Sollte ich die Grenze auf der Client-Seite entfernen oder auf Server eins abschneiden? Denn dieser Dienst sollte auch von JS verwendet werden, und ich weiß nicht, ob es solche zusätzlichen Informationen enthält oder nicht.

Client-Seite sendet eine Anfrage wie folgt aus:

public async Task<FileMetadata> Upload(string fileName, RequestType requestType, Stream stream) 
{ 
    var requestUri = $"Upload?fileName={fileName}&requestType={requestType}"; 
    using (var requestContent = new MultipartFormDataContent()) 
    { 
     requestContent.Add(new StreamContent(stream)); 
     var response = await _client.PostAsync(requestUri, requestContent).ConfigureAwait(false); 
     if (response.IsSuccessStatusCode) 
     { 
      var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); 
      return JsonConvert.DeserializeObject<FileMetadata>(responseContent); 
     } 
    } 
    throw new Exception(); 
} 

Es funktioniert gut mit HttpWebRequest, aber ich möchte modernere apporach verwenden. Ich bin sicher, ich bin etwas falsch zu machen, bitte Rat:

public FileMetadata Upload(string fileName, RequestType requestType, Stream stream) 
{ 
    var requestUri = $"Upload?fileName={fileName}&requestType={requestType}"; 
    var request = WebRequest.CreateHttp(new Uri(_client.BaseAddress, requestUri)); 
    request.Method = "POST"; 
    request.AllowWriteStreamBuffering = false; 
    request.ContentLength = stream.Length; 
    using (var requestStream = request.GetRequestStream()) 
    { 
     stream.CopyTo(requestStream); 
    } 
    using (var response = (HttpWebResponse) request.GetResponse()) 
    { 
     if (response.StatusCode != HttpStatusCode.OK) 
     { 
      throw new Exception(); 
     } 
     using (var sr = new StreamReader(response.GetResponseStream())) 
     { 
      return JsonConvert.DeserializeObject<FileMetadata>(sr.ReadToEnd()); 
     } 
    } 
} 

Antwort

0

Gelöst: nur StreamContent allein verwenden, ohne in MultipardFormDataContent Verpackung. Codebeispiel:

public async Task<FileMetadata> Upload(string fileName, RequestType requestType, Stream stream) 
{ 
    var requestUri = $"Upload?fileName={fileName}&requestType={requestType}"; 
    var response = await _client.PostAsync(requestUri, new StreamContent(stream)).ConfigureAwait(false); 
    if (response.IsSuccessStatusCode) 
    { 
     var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); 
     return JsonConvert.DeserializeObject<FileMetadata>(responseContent); 
    } 
    throw new Exception(); 
}