WCF REST Upload File (некоторые файлы успешно - 200, некоторые - 400 Bad Request) - PullRequest
1 голос
/ 19 апреля 2011

Вот моя конечная точка WCF REST:

[WebInvoke(Method = "POST", UriTemplate = "_test/upload")]
public void UploadImage(Stream data)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.OK;
    try
    {
        var parser = new MultipartParser(data);
        var ext = Path.GetExtension(parser.Filename);
        var filename = string.Format("{0}{1}", Guid.NewGuid().ToString("N"), ext);
        var folder = HttpContext.Current.Server.MapPath(@"~\Uploads\");
        var filepath = Path.Combine(folder, filename);
        File.WriteAllBytes(filepath, parser.FileContents);
    }
    catch (Exception)
    {
        WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError;
    }
}

И я использую многочастный парсер отсюда: http://antscode.blogspot.com/2009/11/parsing-multipart-form-data-in-wcf.html

Моя проблема в том, что вышеописанное прекрасно работает для некоторых файлов (.bat, .txt, .cs, .doc) - я вижу в Fiddler все хорошие признаки, включая статус 200 (ОК).

Когда я пытаюсь загрузить другие файлы (.xls, .vsd), происходит сбой со статусом 400 (неверный запрос). Я очень удивлен, что .doc сработает, а .xls и .vsd потерпят неудачу.

Это также соответствует. Я успешно загрузил несколько файлов .doc без сбоев. Я также попытался загрузить несколько файлов .xls - некоторые удаются, некоторые терпят неудачу (успехи повторяются снова и снова, неудачи повторяются снова и снова). Когда я пишу это и проверяю все больше и больше файлов, появляется файл .pdf, который последовательно выдает ошибку 504 (Fiddler - Receive Failure).

К вашему сведению, я использую Flex на клиенте и использую класс FileReference для выполнения загрузки. Код Flex является стандартным в том виде, в каком он есть - используя этот код, единственное изменение - URL REST WCF: http://blog.flexexamples.com/2007/09/21/uploading-files-in-flex-using-the-filereference-class/

Есть идеи, почему я вижу некоторые неудачи и некоторые успехи? Я не вижу разницы между этими двумя?

Заранее спасибо.

1 Ответ

2 голосов
/ 18 мая 2011

Вы можете проверить размеры файлов, которые следуют, и настроить maxReceivedMessageSize вашего webHttpBinding в web.config. Это только 64 КБ по умолчанию. У меня была похожая проблема, пока я не поднял ее вверх (здесь мы умножаем ее на 1000). Также установите для requestValidationMode значение 2.0, а для pages.validateRequest значение false, чтобы предотвратить блокировку «опасных» загрузок.

Эти изменения заставили меня работать, но у меня возникли проблемы с файлами размером более 4 МБ (независимо от настройки maxReceivedMessageSize); исправление, которое требовало увеличения maxRequestLength для httpRuntime.

Я установил для TransferMode значение StreamedRequest, но не уверен, что последствия загрузки файлов этим способом влияют на производительность IIS и / или атаки типа «отказ в обслуживании». Я думаю, что это должно быть довольно безопасно с потоковым режимом. Вот достойная статья MSDN о больших данных и потоковой передаче . Ранее я использовал чанкинг-клиенты, чтобы избежать таких больших запросов.

<system.web>
    <httpRuntime requestValidationMode="2.0" maxRequestLength="65536000" />
    <pages validateRequest="false" />

<!-- (etc.) -->
</system.web>
<!-- (etc.) -->
<system.serviceModel>
     <bindings>
         <webHttpBinding>
             <binding maxReceivedMessageSize="65536000" transferMode="StreamedRequest">
                <security mode="None" />
              </binding>
         </webHttpBinding>
    </bindings>
</system.serviceModel>
...