英文:
How to call file upload (IFormFile) api in ASP.NET Core web api project from ASP.NET webform using WebClient?
问题
抱歉,代码部分不需要翻译。以下是翻译好的内容:
"I have created one API in ASP.NET Core 3.1 project for file uploading. This api working fine when I called api from Postman or any other .NET Core project using HttpClient. But I am unable to call this api from Webform using WebClient.
After uploading file on server (where ASP.NET Core web API project is deployed), I will get a response like: uploaded file path and name."
英文:
I have created one API in ASP.NET Core 3.1 project for file uploading. This api working fine when I called api from Postman or any other .NET Core project using HttpClient. But I am unable to call this api from Webform using WebClient.
[HttpPost("Upload")]
public IActionResult Upload([FromForm] IFormFile fileUpload)
{
ResponseViewModel responseModel = new ResponseViewModel();
try
{
if (fileUpload == null)
{
responseModel.Message = "Please select file.";
return BadRequest(responseModel);
}
//file upload to temp folder
string tempFilPathWithName = Path.GetTempFileName();
using (FileStream file = System.IO.File.OpenWrite(tempFilPathWithName))
{
fileUpload.CopyTo(file);
}
UploadFile uploadFile = new UploadFile()
{
FileName = fileUpload.FileName,
TempFilPathWithName = tempFilPathWithName
};
responseModel.Model = uploadFile;
responseModel.Message = "File successfully uploaded";
return Ok(responseModel);
}
catch (Exception ex)
{
responseModel.ExceptionMessage = ex.ToString();
responseModel.Message = "File upload failed.";
}
return BadRequest(responseModel);
}
public class ResponseViewModel
{
public object Model { get; set; }
public string ExceptionMessage { get; set; }
public string Message { get; set; }
}
After uploading file on server (where ASP.NET Core wep api project deploy) I will getting response like: uploaded file path and name.
答案1
得分: 1
这个API在我从Postman或任何其他.NET Core项目使用HttpClient调用时工作正常。但是我无法从Webform使用WebClient调用此API。
如果您能详细分享您的请求代码片段,那将更好,但除此之外,您可以使用HttpClient来实现这个目标。
此外,从ASP.NET Webform项目发送文件请求,您需要使用MultipartFormDataContent,以便根据您的需求来实现。
在服务器上上传文件(ASP.NET Core Web API项目部署的地方)后,我将获得响应,如:上传的文件路径和名称。
让我们快速演示如何有效地实现这一操作:
从ASP.NET Webform上传文件到ASP.NET Core Web API:
public partial class Contact : Page
{
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(UploadFileFromAspDotNetWebFormToWebAPI));
}
static readonly HttpClient client = Client.GetClient();
private async Task UploadFileFromAspDotNetWebFormToWebAPI()
{
//绑定文件位置
var readFileData = System.IO.File.ReadAllBytes(@"D:\Md Farid Uddin Resume.pdf");
//创建多部分请求
var formContent = new MultipartFormDataContent();
formContent.Add(new StreamContent(new MemoryStream(readFileData)), "fileUpload", "fileUpload");
var response = await client.PostAsync("https://localhost:7132/api/Upload/UploadFromWebFromToWebAPI", formContent);
if (response.IsSuccessStatusCode)
{
var readResponse = await response.Content.ReadAsStringAsync();
ResponseViewModel readApiResponse = JsonConvert.DeserializeObject<ResponseViewModel>(readResponse);
}
}
}
注意: 这里需要特别注意,在StreamContent中,您应该将请求参数与控制器参数定义保持一致。在您的情况下,控制器名称是fileUpload,因此它应该完全匹配,最后一个是您要传递的文件名,这是必需的,我将其保持相同,但您可以放置任何东西。否则,请求将无法到达终点。
响应模型:
public class ResponseViewModel
{
public object Model { get; set; }
public string ExceptionMessage { get; set; }
public string Message { get; set; }
}
输出:
最后但并非最不重要的,对于API代码段,我已经使用您的示例进行了测试,但我个人更喜欢以下方式,并希望将文件保存在wwwroot下。
API文件操作:
[HttpPost("UploadFromWebFromToWebAPI")]
public async Task<IActionResult> UploadFromWebFromToWebAPI([FromForm] IFormFile formFile)
{
if (formFile.FileName == null)
{
return BadRequest();
}
var path = Path.Combine(_environment.WebRootPath, "Files/", formFile.FileName);
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await formFile.CopyToAsync(stream);
stream.Close();
}
UploadFile uploadFile = new UploadFile()
{
FileName = formFile.FileName,
TempFilPathWithName = path
};
var responseViewModel = new ResponseViewModel();
responseViewModel.Model = uploadFile;
responseViewModel.Message = "File Uploaded...";
responseViewModel.ExceptionMessage = "N/A";
return Ok(responseViewModel);
}
注意: 如果您想了解更多详细信息,您可以在这里查看我们的官方文档。
英文:
> This api working fine when I called api from Postman or any other
> .NET Core project using HttpClient. But I am unable to call this api
> from Webform using WebClient.
It would be nicer if you could share your request code snippet in details but apart from this you could achieve the using HttpClient.
In addition to this, sending file request from ASP.NET webform project you would require MultipartFormDataContent so that you can implement your requirement accordingly.
> After uploading file on server (where ASP.NET Core wep api project
> deploy) I will getting response like: uploaded file path and name.
Let's have a look on a quick demonstration how we can efficiently implement that in action:
File Upload From ASP.NET webform To Asp.net Core Web API:
<!-- language: c# -->
public partial class Contact : Page
{
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(UploadFileFromAspDotNetWebFormToWebAPI));
}
static readonly HttpClient client = Client.GetClient();
private async Task UploadFileFromAspDotNetWebFormToWebAPI()
{
//Bind your file location
var readFileData = System.IO.File.ReadAllBytes(@"D:\Md Farid Uddin Resume.pdf");
//Create Multipart Request
var formContent = new MultipartFormDataContent();
formContent.Add(new StreamContent(new MemoryStream(readFileData)), "fileUpload", "fileUpload");
var response = await client.PostAsync("https://localhost:7132/api/Upload/UploadFromWebFromToWebAPI", formContent);
if (response.IsSuccessStatusCode)
{
var readResponse = await response.Content.ReadAsStringAsync();
ResponseViewModel readApiResponse = JsonConvert.DeserializeObject<ResponseViewModel>(readResponse);
}
}
}
Note: Important point to keep in find here, in StreamContent you should match request parameter as same as your controller parameter defination. In your scenario, your controller name is fileUpload; Thus, it should be matched exactly and last one is file name you want to pass which is mandatory and I kept that same but you can put anything. Otherwise, request would not reach to endpoint.
Response Model:
<!-- language: c# -->
public class ResponseViewModel
{
public object Model { get; set; }
public string ExceptionMessage { get; set; }
public string Message { get; set; }
}
Output:
Last but not least, for API code snippet I have tested with your sample but I personally prefer following way and I like to keep my files under wwwroot.
API File Operation:
<!-- language: c# -->
[HttpPost("UploadFromWebFromToWebAPI")]
public async Task<ActionResult> UploadFromWebFromToWebAPI([FromForm] IFormFile formFile)
{
if (formFile.FileName == null)
{
return BadRequest();
}
var path = Path.Combine(_environment.WebRootPath, "Files/", formFile.FileName);
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await formFile.CopyToAsync(stream);
stream.Close();
}
UploadFile uploadFile = new UploadFile()
{
FileName = formFile.FileName,
TempFilPathWithName = path
};
var responseViewModel = new ResponseViewModel();
responseViewModel.Model = uploadFile;
responseViewModel.Message = "File Uploaded...";
responseViewModel.ExceptionMessage = "N/A";
return Ok(responseViewModel);
}
Note: If you would like to know more details on it you could check our official document here.
答案2
得分: 0
以下是代码的中文翻译:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace WebApplication
{
public partial class User : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
string filePath = @"C:\temp\excelsheet.xlsx";
string apiToken = "BearerToken";
NameValueCollection headers = new NameValueCollection();
headers.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {apiToken}");
List<FileInfo> files = new List<FileInfo>() { new FileInfo(filePath) };
MultiPartFormUpload multiPartFormUpload = new MultiPartFormUpload();
MultiPartFormUpload.UploadResponse response = multiPartFormUpload.Upload("https://localhost:5001/api/FileUpload/Upload", headers, new NameValueCollection() { }, files);
}
catch (Exception ex)
{
throw ex;
}
}
}
public class MultiPartFormUpload
{
public class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("--");
stringBuilder.Append(boundary);
stringBuilder.AppendLine();
foreach (string key in _headers.AllKeys)
{
stringBuilder.Append(key);
stringBuilder.Append(": ");
stringBuilder.AppendLine(_headers[key]);
}
stringBuilder.AppendLine();
_header = Encoding.UTF8.GetBytes(stringBuilder.ToString());
return _header.Length + Data.Length + 2;
}
public Stream Data { get; set; }
}
public class UploadResponse
{
public UploadResponse(HttpStatusCode httpStatusCode, string responseBody)
{
HttpStatusCode = httpStatusCode;
ResponseBody = responseBody;
}
public HttpStatusCode HttpStatusCode { get; set; }
public string ResponseBody { get; set; }
}
public UploadResponse Upload(string url, NameValueCollection requestHeaders, NameValueCollection requestParameters, List<FileInfo> files)
{
using (WebClient client = new WebClient())
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in requestHeaders.AllKeys)
{
client.Headers.Add(key, requestHeaders[key]);
}
foreach (string key in requestParameters.AllKeys)
{
MimePart part = new MimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));
mimeParts.Add(part);
}
foreach (FileInfo file in files)
{
MimePart part = new MimePart();
string name = "fileUpload";
string fileName = file.Name;
part.Headers["Content-Disposition"] = "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\"";
part.Headers["Content-Type"] = "application/octet-stream";
part.Data = new MemoryStream(File.ReadAllBytes(file.FullName));
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
client.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart mimePart in mimeParts)
{
contentLength += mimePart.GenerateHeaderFooterData(boundary);
}
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (MemoryStream memoryStream = new MemoryStream())
{
foreach (MimePart mimePart in mimeParts)
{
memoryStream.Write(mimePart.Header, 0, mimePart.Header.Length);
while ((read = mimePart.Data.Read(buffer, 0, buffer.Length)) > 0)
memoryStream.Write(buffer, 0, read);
mimePart.Data.Dispose();
memoryStream.Write(afterFile, 0, afterFile.Length);
}
memoryStream.Write(_footer, 0, _footer.Length);
var ss = memoryStream.ToArray();
byte[] responseBytes = client.UploadData(url, memoryStream.ToArray());
string responseString = Encoding.UTF8.GetString(responseBytes);
return new UploadResponse(HttpStatusCode.OK, responseString);
}
}
catch (Exception ex)
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
if (ex.GetType().Name == "WebException")
{
WebException webException = (WebException)ex;
HttpWebResponse response = (HttpWebResponse)webException.Response;
string responseString;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
responseString = reader.ReadToEnd();
}
return new UploadResponse(response.StatusCode, responseString);
}
else
{
throw;
}
}
}
}
}
}
希望这个翻译对您有所帮助。如果您有任何其他问题,欢迎提出。
英文:
Finally, I found the solution to my question. Using the below code we call file upload (IFormFile) API in ASP.NET Core web API project from ASP.NET webform using WebClient.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace WebApplication
{
public partial class User : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
string filePath = @"C:\temp\excelsheet.xlsx";
string apiToken = "BearerToken";
NameValueCollection headers = new NameValueCollection();
headers.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {apiToken}");
List<FileInfo> files = new List<FileInfo>() { new FileInfo(filePath) };
MultiPartFormUpload multiPartFormUpload = new MultiPartFormUpload();
MultiPartFormUpload.UploadResponse response = multiPartFormUpload.Upload("https://localhost:5001/api/FileUpload/Upload", headers, new NameValueCollection() { }, files);
}
catch (Exception ex)
{
throw ex;
}
}
}
public class MultiPartFormUpload
{
public class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("--");
stringBuilder.Append(boundary);
stringBuilder.AppendLine();
foreach (string key in _headers.AllKeys)
{
stringBuilder.Append(key);
stringBuilder.Append(": ");
stringBuilder.AppendLine(_headers[key]);
}
stringBuilder.AppendLine();
_header = Encoding.UTF8.GetBytes(stringBuilder.ToString());
return _header.Length + Data.Length + 2;
}
public Stream Data { get; set; }
}
public class UploadResponse
{
public UploadResponse(HttpStatusCode httpStatusCode, string responseBody)
{
HttpStatusCode = httpStatusCode;
ResponseBody = responseBody;
}
public HttpStatusCode HttpStatusCode { get; set; }
public string ResponseBody { get; set; }
}
public UploadResponse Upload(string url, NameValueCollection requestHeaders, NameValueCollection requestParameters, List<FileInfo> files)
{
using (WebClient client = new WebClient())
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in requestHeaders.AllKeys)
{
client.Headers.Add(key, requestHeaders[key]);
}
foreach (string key in requestParameters.AllKeys)
{
MimePart part = new MimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));
mimeParts.Add(part);
}
foreach (FileInfo file in files)
{
MimePart part = new MimePart();
string name = "fileUpload"; //file.Extension.Substring(1);
string fileName = file.Name;
part.Headers["Content-Disposition"] = "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\"";
part.Headers["Content-Type"] = "application/octet-stream";
part.Data = new MemoryStream(File.ReadAllBytes(file.FullName));
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
client.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart mimePart in mimeParts)
{
contentLength += mimePart.GenerateHeaderFooterData(boundary);
}
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (MemoryStream memoryStream = new MemoryStream())
{
foreach (MimePart mimePart in mimeParts)
{
memoryStream.Write(mimePart.Header, 0, mimePart.Header.Length);
while ((read = mimePart.Data.Read(buffer, 0, buffer.Length)) > 0)
memoryStream.Write(buffer, 0, read);
mimePart.Data.Dispose();
memoryStream.Write(afterFile, 0, afterFile.Length);
}
memoryStream.Write(_footer, 0, _footer.Length);
var ss = memoryStream.ToArray();
byte[] responseBytes = client.UploadData(url, memoryStream.ToArray());
string responseString = Encoding.UTF8.GetString(responseBytes);
return new UploadResponse(HttpStatusCode.OK, responseString);
}
}
catch (Exception ex)
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
if (ex.GetType().Name == "WebException")
{
WebException webException = (WebException)ex;
HttpWebResponse response = (HttpWebResponse)webException.Response;
string responseString;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
responseString = reader.ReadToEnd();
}
return new UploadResponse(response.StatusCode, responseString);
}
else
{
throw;
}
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论