Recieve/Accept file in WEBDAV from httpwebrequest

2019-08-26 12:21发布

问题:

Suppose I have sample Upload file method like this in POStFile.aspx. This method POST file (upload file) to http WEBDAV url.

public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc) {
        log.Debug(string.Format("Uploading {0} to {1}", file, url));
        string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
        byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

        HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
        wr.ContentType = "multipart/form-data; boundary=" + boundary;
        wr.Method = "POST";
        wr.KeepAlive = true;
        wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

        Stream rs = wr.GetRequestStream();

        string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
        foreach (string key in nvc.Keys)
        {
            rs.Write(boundarybytes, 0, boundarybytes.Length);
            string formitem = string.Format(formdataTemplate, key, nvc[key]);
            byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
            rs.Write(formitembytes, 0, formitembytes.Length);
        }
        rs.Write(boundarybytes, 0, boundarybytes.Length);

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
        string header = string.Format(headerTemplate, paramName, file, contentType);
        byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
        rs.Write(headerbytes, 0, headerbytes.Length);

        FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
        byte[] buffer = new byte[4096];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
            rs.Write(buffer, 0, bytesRead);
        }
        fileStream.Close();

        byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
        rs.Write(trailer, 0, trailer.Length);
        rs.Close();

        WebResponse wresp = null;
        try {
            wresp = wr.GetResponse();
            Stream stream2 = wresp.GetResponseStream();
            StreamReader reader2 = new StreamReader(stream2);
            log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
        } catch(Exception ex) {
            log.Error("Error uploading file", ex);
            if(wresp != null) {
                wresp.Close();
                wresp = null;
            }
        } finally {
            wr = null;
        }
    }

From here

NameValueCollection nvc = new NameValueCollection();
    nvc.Add("id", "TTR");
    nvc.Add("btn-submit-photo", "Upload");
    HttpUploadFile("http://your.server.com/upload", 
         @"C:\test\test.jpg", "file", "image/jpeg", nvc);

Question 1 : Shouldn't the url should be like "http://your.server.com/upload.aspx" instead of "http://your.server.com/upload"

If I give url like "http://your.server.com/upload" then i get 405 error method not found.

So it should point to any page.

Question 2 : How should I receive the post and save the file in upload.aspx.

Can the file directly uploaded to remote server without any receiving page ?

回答1:

This question was about "File transfer to WEBDAV http URL using or POST or PUT method"

Above is sample POST method.Similarly there can by PUT method which is little different from POST method.

Question 1 : Shouldn't the url should be like "http://your.server.com/upload.aspx" instead of "http://your.server.com/upload"

For novice man like me, main confusion is URL.It entirely depend upon "How WEBDAV server want to receive POST or PUT method ?"

I think for POST method ,there should be one receiving page which accept file and other parameters from POSTfile page and save the file to disk.

I don't know about .net code but WEB API has inbuilt feature which can parse data like "multipart/form-data; boundary=---------------------------8d60ff73d4553cc"

Below code is just sample code,

[HttpPost]
        public async Task<FileUploadDetails> Post()
        {
            // file path
            var fileuploadPath = HttpContext.Current.Server.MapPath("~/UploadedFiles");

            //// 
            var multiFormDataStreamProvider = new MultiFileUploadProvider(fileuploadPath);

            // Read the MIME multipart asynchronously 
            await Request.Content.ReadAsMultipartAsync(multiFormDataStreamProvider);

            string uploadingFileName = multiFormDataStreamProvider
                .FileData.Select(x => x.LocalFileName).FirstOrDefault();

            // Files
            //
            foreach (MultipartFileData file in multiFormDataStreamProvider.FileData)
            {
                Debug.WriteLine(file.Headers.ContentDisposition.FileName);
                Debug.WriteLine("File path: " + file.LocalFileName);
            }

            // Form data
            //
            foreach (var key in multiFormDataStreamProvider.FormData.AllKeys)
            {
                foreach (var val in multiFormDataStreamProvider.FormData.GetValues(key))
                {
                    Debug.WriteLine(string.Format("{0}: {1}", key, val));
                }
            }
             //Create response
            return new FileUploadDetails
            {

                FilePath = uploadingFileName,

                FileName = Path.GetFileName(uploadingFileName),

                FileLength = new FileInfo(uploadingFileName).Length,

                FileCreatedTime = DateTime.Now.ToLongDateString()
            };
            return null;
        }

So url in POSTFile.aspx page should point to API method in this case,

"http://your.server.com/api/fileUpload"

where fileUpload is api controller name.

If you are using HTTP PUT method then

i) you want to receive it in pro grammatically handle it.Write PUT method similar to POST method in api class.

ii) you want to directly save the file to folder using PUT method.

so URL in this case can be,

"http://your.server.com/Imagefolder"

Yes this can be done with extra IIS setting.

Create virtual directory in Target folder,beside few other thing.