2017-06-07 10 views
15

में रूट पैरामीटर तक पहुंच के साथ संयोजन में फ़ाइल अपलोड का खंडित हस्तांतरण मैं सर्विसस्टैक (v3) और खंडित स्थानांतरण एन्कोडिंग का उपयोग करके बड़ी फ़ाइल अपलोड (वीडियो फ़ाइलों) को सक्षम करने के लिए IRequiresRequestStream इंटरफ़ेस का उपयोग करना चाहता हूं। मानक फ़ाइल अपलोड हमारे ग्राहकों को अपलोड करने वाली कुछ बड़ी वीडियो फ़ाइलों से निपटने के लिए प्रतीत नहीं होता है, इसलिए हम इन फ़ाइलों के लिए खंडित स्थानांतरण एन्कोडिंग को सक्षम करने के लिए देख रहे हैं।सी # सर्विसस्टैक

मैंने सफलतापूर्वक खंडित ट्रांसफर एन्कोडेड फ़ाइल अपलोड का परीक्षण किया है, लेकिन फ़ाइल के साथ कई पैरामीटर भी भेजे जाने की आवश्यकता है।

चूंकि IRequiresRequestStream सर्विसस्टैक अनुरोध ऑब्जेक्ट पार्सर को छोड़ देता है, Stream के साथ अनुरोध ऑब्जेक्ट में कोई अन्य पैरामीटर स्पष्ट रूप से पॉप्युलेट नहीं है। RequestBinder के माध्यम से

  1. क्वेरी स्ट्रिंग पैरामीटर, this.Request.QueryString संग्रह
  2. कस्टम हेडर मानकों के माध्यम से सुलभ, सुलभ this.Request.Headers संग्रह
  3. पथ के माध्यम से, सुलभ ??: एक काम के रूप में चारों ओर मैं इन विकल्पों को देख सकते हैं

मैं पहले से ही विकल्पों 1 और 2 को लागू करने में कामयाब रहा हूं, लेकिन किसी भी तरह से न तो काफी पर्याप्त महसूस कर रहा है। मैं 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(); 
} 

मैं लेने के लिए निम्नलिखित लाइनों के साथ कुछ है सरल दिशा अनुमान लगा रहा हूँ, लेकिन ऐसा लगता है एक झुकाव की तरह।

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; 
}); 

मैं इस परिदृश्य में RequestBinders के उदाहरण के लिए Googling का एक सा किया है। मुझे यकीन है कि Path को पार्स करने के लिए इनबिल्ट सर्विसस्टैक विधियां होनी चाहिए, लेकिन मैं इसके साथ संघर्ष कर रहा हूं। क्या किसी के पास एक उदाहरण है जिसे वे साझा करना चाहते हैं?

उत्तर

1

हाल ही में मैंने कस्टम हेडर के साथ चंक किए गए स्थानांतरण का उपयोग करके भी जांच की। दुर्भाग्यवश, मुझे पता चला कि यह HttpWebRequest क्लास में न ही बॉक्स में समर्थित है और न ही सामान्य रूप से .NET Framework में। मेरे लिए काम करने वाला एकमात्र समाधान टीसीपी पर चंकड ट्रांसफर HTTP संचार को लागू करना था। यह उतना जटिल नहीं है जितना कि यह भिखारी में लगता है। आपको बस टीसीपी क्लाइंट कनेक्शन खोलने की जरूरत है, हेडर को आवश्यकतानुसार प्रारूपित करें, अपनी स्ट्रीम को टुकड़ों से विभाजित करें और इसे भेजें।

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding

:

यहाँ chunked स्थानांतरण प्रोटोकॉल की परिभाषा है

संबंधित मुद्दे