Подтвердить что ты не робот

С# Перемещенная передача загрузки файла в сочетании с доступом к параметрам маршрута в ServiceStack

Я хочу использовать интерфейс IRequiresRequestStream для включения больших загрузок файлов (видеофайлов) с использованием ServiceStack (v3) и кодирования с передачей пакетов. Стандартная загрузка файла, похоже, не справляется с некоторыми из более крупных видеофайлов, которые загружаются нашими клиентами, поэтому мы хотим включить кодировку с короткими передачами для этих файлов.

Я успешно протестировал загрузку загруженного файла с кодировкой передачи, но есть ряд параметров, которые также необходимо отправить вместе с файлом.

Так как IRequiresRequestStream обходит анализатор объектов запроса ServiceStack, любые другие параметры объекта запроса рядом с Stream, очевидно, не заполняются. Во время работы я вижу следующие варианты:

  • Параметры строки запроса, доступные через коллекцию this.Request.QueryString
  • Пользовательские параметры заголовка, доступные через коллекцию this.Request.Headers
  • Путь, доступный через RequestBinder??

Мне уже удалось реализовать опции 1 и 2, но так или иначе не чувствую себя достаточно RESTful. Я бы предпочел использовать Path -> RequestDTO, но я боюсь с RequestBinder.

Услуги:

public object Any(AttachmentStreamRequest request)
{
    byte[] fileBytes = null;

    using (var stream = new MemoryStream())
    {
        request.RequestStream.WriteTo(stream);
        length = stream.Length;
        fileBytes = stream.ToArray();
    }

    string filePath = @"D:\temp\test.dat";
    File.WriteAllBytes(filePath, fileBytes);

    var hash = CalculateMd5(filePath);
    var requestHash = this.Request.QueryString["Hash"];
    var customerId = this.Request.QueryString["CustomerId"];
    var fileName = this.Request.QueryString["FileName"];

    // nicer would be
    // var requestHash = request.Hash;
    // var customerId = request.CustomerId;

    // save file....

    // return response
    return requestHash == hash
               ? new HttpResult("File Valid", HttpStatusCode.OK)
               : new HttpResult("Invalid Hash", HttpStatusCode.NotAcceptable);
}

Запрос:

[Route("/upload/{CustomerId}/{Hash}", "POST", Summary = @"POST Upload attachments for a customer", Notes = "Upload customer attachments")]
public class AttachmentStreamRequest : IRequiresRequestStream
{
    // body
    public Stream RequestStream { get; set; }

    // path    
    public int CustomerId { get; set; }

    // query
    public string FileName { get; set; }

    // query
    public string Comment { get; set; }

    // query
    public Guid? ExternalId { get; set; }

    // path
    public string Hash { get; set; }
}

WebClient:

private static async Task<string> SendUsingWebClient(byte[] file, string hash, customerId)
{
    var client = (HttpWebRequest)WebRequest.Create(string.Format("http://localhost.fiddler:58224/upload/{0}/{1}", customerId, hash));
    client.Method = WebRequestMethods.Http.Post;
    client.Headers.Add("Cookie", "ss-pid=XXXXXXXXXXX; ss-id=YYYYYYYYYY");

    // the following 4 rows enable streaming 
    client.AllowWriteStreamBuffering = false;
    client.SendChunked = true;
    client.ContentType = "application/json";
    client.Timeout = int.MaxValue;

    using (var fileStream = new MemoryStream(file))
    {
        fileStream.Copy(client.GetRequestStream());
    }

    return new StreamReader(client.GetResponse().GetResponseStream()).ReadToEnd();
}

Я предполагаю, что простое направление - это что-то в следующих строках, но это похоже на kludge.

RequestBinders.Add(typeof(AttachmentStreamRequest), httpReq => { 
    var dto = new AttachmentStreamRequest(); 
    var segments = base.Request.PathInfo.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

    dto.CustomerId = segments[1].As<int32>();
    dto.Hash = segments[2].As<string>();

    // Stream copy to dto.RequestStream and other params etc....

    return dto;
});

В этом сценарии я немного использовал Google для примеров RequestBinders. Я уверен, что должны быть встроенные методы ServiceStack для разбора Path, но я борюсь с ним. Есть ли у кого-нибудь пример, который они хотели бы поделиться?

4b9b3361