如何使用WebClient Windows手机在服务器上上传文件?

时间:2014-03-17 15:19:58

标签: windows-phone-8 upload webclient

我想在服务器上上传文件(任何类型)。

我的文件是这样保存的(我使用FileAssociation)

 
await SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, "fileToSave" + fileext, NameCollisionOption.ReplaceExisting, NavigationContext.QueryString["filetoken"]);

然后我得到保存的文件

                StorageFolder folder = ApplicationData.Current.LocalFolder;
                var file = await folder.GetFileAsync("fileToSave" + fileext);
                Stream data = Application.GetResourceStream(new Uri(file.Path, UriKind.Relative)).Stream;
                string filename = System.IO.Path.GetFileName(file.Path);
                ServerFunctions.UploadFile(filename,data);  

然后我开始上传

 internal void UploadFile(string fileName,Stream data)
        {
            WebClient web = new WebClient();
            if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin))
            {
                System.Net.NetworkCredential account = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword);
                web.Credentials = account;
            }

            web.AllowReadStreamBuffering = true;
            web.AllowWriteStreamBuffering = true;


            web.OpenWriteCompleted += (sender, e) =>
            {
                PushData(data, e.Result);
                e.Result.Close();
                data.Close();

            };
            web.OpenWriteAsync(dataRequestParam.TargetUri,"POST");
        }

        private void PushData(Stream input, Stream output)
        {
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
            {
                output.Write(buffer, 0, bytesRead);
            }
        }

Web服务器应该将我作为响应发送给我,其中包含错误代码或成功代码。 没有错误被抛出,但它不起作用。我不明白为什么e.result是一个流对象。正如我所说,服务器应该返回一个字符串......(xml文件)
你能否给我一些关于我的代码中发生的事情的解释,以及它是否适用于所有类型的文件?

由于

2 个答案:

答案 0 :(得分:0)

我认为这里的部分问题是,当你想要一个请求/响应类型架构时,你试图让它像流媒体协议一样运行。出于这些目的,您应该考虑使用WebRequest对象。

请耐心等待我完全限定内联对象的命名空间,因此它可能会有点冗长,但我希望您知道在哪里可以找到这些东西。

internal async void UploadFile(string fileName, System.IO.Stream data)
{
    // Specify URI, method, and credentials for the request
    System.Net.WebRequest web = System.Net.HttpWebRequest.CreateHttp(dataRequestParam.TargetUri);
    web.Method = "POST";

    if (!string.IsNullOrEmpty(dataRequestParam.AuthenticationLogin))
    {
        web.Credentials = new System.Net.NetworkCredential(dataRequestParam.AuthenticationLogin, dataRequestParam.AuthenticationPassword);
    }

    // Create the request payload from the provided stream
    System.IO.Stream requestStream =
        await System.Threading.Tasks.Task<System.IO.Stream>.Factory.FromAsync(web.BeginGetRequestStream, web.EndGetRequestStream, null);
    await data.CopyToAsync(requestStream);

    // Get a response from the server
    System.Net.WebResponse response =
        await System.Threading.Tasks.Task<System.Net.WebResponse>.Factory.FromAsync(web.BeginGetResponse, web.EndGetResponse, null);

    // Possibly parse the response with an XmlReader (example only)
    System.Xml.XmlReader reader = System.Xml.XmlReader.Create(response.GetResponseStream());
    string responseText = reader.ReadInnerXml(); // TODO: Real work here
}

这里的一个奇怪之处是使用Task工厂从begin和end方法创建一个任务来获取请求流和响应。这使得使用这些方法变得更加简单,因为你得到一个可以为其返回对象等待的Task,然后你可以直接操作它。

我不确定您的服务器响应成功与失败的形式是什么形式,因此我只是简单地展示了如何创建XML阅读器以从结果流中解析XML。您可以在这些行上自行完成任何必要的解析,但这至少应该让您了解服务器返回的内容。

答案 1 :(得分:0)

我使用的最终代码。

 WebRequest web = HttpWebRequest.CreateHttp(dataRequestParam.TargetUri);

               web.ContentType = dataRequestParam.ContentType;
               web.Method = "POST";
               web.ContentLength = data.Length;


                if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin))
                {
                    web.Credentials = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword);
                }


                using (var requestStream = await Task<Stream>.Factory.FromAsync(web.BeginGetRequestStream, web.EndGetRequestStream, web))
                {
                    await data.CopyToAsync(requestStream);
                }


                WebResponse responseObject = await Task<WebResponse>.Factory.FromAsync(web.BeginGetResponse, web.EndGetResponse, web);
                var responseStream = responseObject.GetResponseStream();
                var sr = new StreamReader(responseStream);
                string received = await sr.ReadToEndAsync();

                return received;
            }