使用Windows.Web.Http将文件从UWP应用程序上载到WebAPI Web服务

时间:2018-03-29 21:55:31

标签: c# rest xaml asp.net-web-api uwp

我的Windows 10 UWP应用程序正在调用我创建的WebAPI Web服务。我需要从UWP应用程序向服务器发送JPG文件,以便服务器可以将其存储到另一个应用程序中。

我正在使用using Windows.Web.Http;作为UWP的建议,并使用Windows身份验证连接到服务器。

当我使用以下代码执行POST时,我得到 IRandomAccessStream不支持GetInputStreamAt方法,因为它需要克隆错误,如下所示。

我可以将HttpStringContent发布到同一个网络服务,并毫无问题地收到回复。

问题是尝试使用HttpStreamContent将文件发送到网络服务时。

public async void Upload_FileAsync(string WebServiceURL, string FilePathToUpload)
{

    //prepare HttpStreamContent
    IStorageFile storageFile = await StorageFile.GetFileFromPathAsync(FilePathToUpload);
    IBuffer buffer = await FileIO.ReadBufferAsync(storageFile);
    byte[] bytes = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(buffer);
    Stream stream = new MemoryStream(bytes);
    Windows.Web.Http.HttpStreamContent streamContent = new Windows.Web.Http.HttpStreamContent(stream.AsInputStream());


    //send request
    var myFilter = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
    myFilter.AllowUI = false;
    var client = new Windows.Web.Http.HttpClient(myFilter);
    Windows.Web.Http.HttpResponseMessage result = await client.PostAsync(new Uri(WebServiceURL), streamContent);
    string stringReadResult = await result.Content.ReadAsStringAsync();

}

完全错误:

  

{System.NotSupportedException:此IRandomAccessStream不支持GetInputStreamAt方法,因为它需要克隆,并且此流不支持克隆。      在System.IO.NetFxToWinRtStreamAdapter.ThrowCloningNotSuported(String methodName)      在System.IO.NetFxToWinRtStreamAdapter.GetInputStreamAt(UInt64位置)   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()      at}

请帮忙!

2 个答案:

答案 0 :(得分:1)

获取文件并开始创建HttpStreamContent实例后,您可以尝试使用StorageFile.OpenAsync方法获取IRandomAccessStream对象,然后将其作为{{1}对象构造函数参数。

代码就是这样,你可以尝试一下。

HttpStreamContent

答案 1 :(得分:0)

在Web API控制器中

public IHostingEnvironment _environment;
public UploadFilesController(IHostingEnvironment environment) // Create Constructor 
{
    _environment = environment;
}

[HttpPost("UploadFiles")]
public Task<ActionResult<string>> UploadFiles([FromForm]List<IFormFile> allfiles)
{
    string filepath = "";
    foreach (var file in allfiles)
    {
        string extension = Path.GetExtension(file.FileName);
        var upload = Path.Combine(_environment.ContentRootPath, "FileFolderName");
        if (!Directory.Exists(upload))
        {
            Directory.CreateDirectory(upload);
        }
        string FileName = Guid.NewGuid() + extension;
        if (file.Length > 0)
        {
            using (var fileStream = new FileStream(Path.Combine(upload, FileName), FileMode.Create))
            {
                file.CopyTo(fileStream);
            }
        }
        filepath = Path.Combine("FileFolderName", FileName);
    }
    return Task.FromResult<ActionResult<string>>(filepath);
}

在yourpage.xaml.cs

using Windows.Storage;
using Windows.Storage.Pickers;
.....
StorageFile file;
......

private async void btnFileUpload_Click(object sender, RoutedEventArgs e) // Like Browse button 
{
    try
    {
        FileOpenPicker openPicker = new FileOpenPicker();
        openPicker.ViewMode = PickerViewMode.Thumbnail;
        openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        openPicker.FileTypeFilter.Add(".pdf");
        file = await openPicker.PickSingleFileAsync();
        if (file != null)
        {
            //fetch file details
        }
    }
    catch (Exception ex)
    {

    }
}

//When upload file
var http = new HttpClient();
var formContent = new HttpMultipartFormDataContent();
var fileContent = new HttpStreamContent(await file.OpenReadAsync());
formContent.Add(fileContent, "allfiles", file.Name);
var response = await http.PostAsync(new Uri("Give API Path" + "UploadFiles", formContent);
string filepath = Convert.ToString(response.Content); //Give path in which file is uploaded

希望此代码可以帮助您...

但是请记住,formContent.Add(fileContent, "allfiles", file.Name);行很重要,而allfiles是在Web api方法"public Task<ActionResult<string>> UploadFiles([FromForm]List<IFormFile> **allfiles**)"中获取文件的参数名称

谢谢!