में रूट पैरामीटर तक पहुंच के साथ संयोजन में फ़ाइल अपलोड का खंडित हस्तांतरण मैं सर्विसस्टैक (v3) और खंडित स्थानांतरण एन्कोडिंग का उपयोग करके बड़ी फ़ाइल अपलोड (वीडियो फ़ाइलों) को सक्षम करने के लिए IRequiresRequestStream
इंटरफ़ेस का उपयोग करना चाहता हूं। मानक फ़ाइल अपलोड हमारे ग्राहकों को अपलोड करने वाली कुछ बड़ी वीडियो फ़ाइलों से निपटने के लिए प्रतीत नहीं होता है, इसलिए हम इन फ़ाइलों के लिए खंडित स्थानांतरण एन्कोडिंग को सक्षम करने के लिए देख रहे हैं।सी # सर्विसस्टैक
मैंने सफलतापूर्वक खंडित ट्रांसफर एन्कोडेड फ़ाइल अपलोड का परीक्षण किया है, लेकिन फ़ाइल के साथ कई पैरामीटर भी भेजे जाने की आवश्यकता है।
चूंकि IRequiresRequestStream
सर्विसस्टैक अनुरोध ऑब्जेक्ट पार्सर को छोड़ देता है, Stream
के साथ अनुरोध ऑब्जेक्ट में कोई अन्य पैरामीटर स्पष्ट रूप से पॉप्युलेट नहीं है। RequestBinder
के माध्यम से
- क्वेरी स्ट्रिंग पैरामीटर,
this.Request.QueryString
संग्रह - कस्टम हेडर मानकों के माध्यम से सुलभ, सुलभ
this.Request.Headers
संग्रह - पथ के माध्यम से, सुलभ ??: एक काम के रूप में चारों ओर मैं इन विकल्पों को देख सकते हैं
मैं पहले से ही विकल्पों 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
को पार्स करने के लिए इनबिल्ट सर्विसस्टैक विधियां होनी चाहिए, लेकिन मैं इसके साथ संघर्ष कर रहा हूं। क्या किसी के पास एक उदाहरण है जिसे वे साझा करना चाहते हैं?