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

C# 使用Windows.Web.Http将文件从UWP应用上载到WebAPI Web服务,c#,rest,xaml,asp.net-web-api,uwp,C#,Rest,Xaml,Asp.net Web Api,Uwp,我的Windows 10 UWP应用程序正在调用我创建的WebAPI web服务。我需要从UWP应用程序向服务器发送一个JPG文件,以便服务器可以将其存储到另一个应用程序中 我正在使用使用Windows.Web.Http推荐用于UWP并使用Windows身份验证连接到服务器 当我使用以下代码执行POST时,我得到irandomaccesstream不支持GetInputStreamAt方法,因为它需要克隆错误,如下所示 我能够将HttpStringContent发布到同一个web服务上,并在没有

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

我正在使用
使用Windows.Web.Http
推荐用于UWP并使用Windows身份验证连接到服务器

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

我能够将
HttpStringContent
发布到同一个web服务上,并在没有任何问题的情况下收到回复

问题在于尝试使用
HttpStreamContent
将文件发送到web服务时

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:此IRandomaccesstream不支持GetInputStreamAt方法,因为它需要克隆,而此流不支持克隆。 在System.IO.NetFxToWinRtStreamAdapter.throwcloningnotsupported处(字符串方法名) 在System.IO.NetFxToWinRtStreamAdapter.GetInputStreamAt处(UInt64位置) ---来自引发异常的上一个位置的堆栈结束跟踪--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中 at}


请帮忙

获取文件并开始创建
HttpStreamContent
实例后,可以尝试使用该方法获取
irandomaccesstream
对象,然后将其作为
HttpStreamContent
对象构造函数参数

代码是这样的,你可以试试

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

    //prepare HttpStreamContent
    IStorageFile storageFile = await StorageFile.GetFileFromPathAsync(FilePathToUpload);

    //Here is the code we changed
    IRandomAccessStream stream=await storageFile.OpenAsync(FileAccessMode.Read);
    Windows.Web.Http.HttpStreamContent streamContent = new Windows.Web.Http.HttpStreamContent(stream);

    //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();
}
在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);
}
希望这段代码能帮助你

但是请记住
formContent.Add(fileContent,“allfiles”,file.Name)行很重要,
allfiles
是在web api方法中获取文件的参数名
“公共任务上载文件([FromForm]列表**allfiles**)”


谢谢

谢谢你的回复!这段代码消除了这个错误。但是,WebAPI web服务端上的函数捕获此调用的样子是什么?我尝试了
public async Task uploadDocumentsSync(byte[]fileUploadRequest)
public async Task uploadDocumentsSync([FromBody]byte[]fileUploadRequest)
,也尝试了
IFormFile
的方法,但它没有捕获随此调用发送的请求。请帮忙!请看这里的其他问题:谢谢你的帮助!!
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