When uploading files to ASP.Net 5 Web API, the collection of IFormFile is empty - asp.net-core

I am trying to upload some files from a console application to an ASP.NET 5 WEB API service.
Client (console app):
private static HttpResponseMessage UploadFiles(string[] files, Uri uploadEndpoint)
{
var message = new HttpRequestMessage();
var content = new MultipartFormDataContent();
foreach (var file in files)
{
var fs = new FileStream(file, FileMode.Open);
var index = file.LastIndexOf(#"\");
var fn = file.Substring(index + 1);
fs.Position = 0;
content.Add(new StreamContent(fs), "file", fn);
}
message.Method = HttpMethod.Post;
message.Content = content;
message.RequestUri = uploadEndpoint;
var client = new HttpClient();
return client.SendAsync(message).Result;
}
Server (Asp.Net 5) Web API
[HttpPost("upload")]
public IActionResult UploadFiles(ICollection<IFormFile> files)
{
var streams = files.Select(f => f.OpenReadStream()).ToArray();
var names = files.Select(f => ContentDispositionHeaderValue.Parse(f.ContentDisposition).FileName).ToArray();
ProcessFiles(streams, names);
return new HttpOkResult();
}
Unfortunately the collection of IFormFile is always empty.
Anyone can tell me why?
Thanks
Manu

Your upload controller expects the name identifier of the posted data to be files, not file.
This line: content.Add(new StreamContent(fs), "file", fn);
should be: content.Add(new StreamContent(fs), "files", fn);
So your code basically works, it was just a simple mistake.

You need to set the enctype of the form to multipart/form-data. Something like this.
<form method="post" asp-action="Index" asp-controller="Home" enctype="multipart/form-data">
<input type="file" name="files" multiple/>
<input type="submit" value="Upload" />
</form>

I ran into this identical issue and it turned out that I was just missing - name="files" from <input type="file" name="files" multiple /> from HTML.

Related

How to fix NullPointerException when uploading picture in database?

I want to upload a picture in database, and this is my jsp:
<body>
<form action="addbooka" method="POST" enctype="multipart/form-data">
Title:<input type="text" value="${title}" name="title"> <br>
Description: <input type="text" value="${description}" name="description"><br>
Price: <input type="text" value="${price}" name="price"><br>
Picture: <input type="file" name="myimg"><br>
<button type="submit">Add</button>
</form>
</body>
And this is method where i insert picture:
public static void insertImage(String myImage) throws Exception {
try {
String insertImage = ("insert into image(image) values(?)");
PreparedStatement ps = DataBaseConnection.get().prepareStatement(insertImage);
File file = new File(myImage);
InputStream in = new FileInputStream(file);
ps.setBlob(1, in);
ps.executeUpdate();
In servlet i just call this method and pass request.getParameter("myimg") as an argument(input tag).
After some research i think i get this error because i did't put boundary in form tag. But i can't wrap my head around what numbers to put, what to do next or is it really error because of boundary or something else?
In your servlet don't forget to put #MultipartConfig annotation.Also , you are passing string to your method instead that should be Part . i.e :
int row=0;
InputStream inputStream = null; // input stream of the upload file
// obtains the upload file part in this multipart request
Part filePart = request.getPart("myimg");//get image
insertImage(filePart)//pass to method
public static void insertImage(Part filePart) throws Exception {
String insertImage = ("insert into image(image) values(?)");
PreparedStatement ps = DataBaseConnection.get().prepareStatement(insertImage);
if (filePart != null) {
// obtains input stream of the upload file
inputStream = filePart.getInputStream();
}
if (inputStream != null) {
// fetches input stream of the upload file for the blob column
ps.setBlob(1, inputStream);
}
row = ps.executeUpdate();
if (row > 0) {
out.println("done")
}
}

Cannot get Blazor file upload to upload file

I have a Blazor app where Im using BlazorInputFile from this website - https://blog.stevensanderson.com/2019/09/13/blazor-inputfile/ however the page only loads it to a Memory Stream, not copy the file to a folder on the server. I need it to copy to a folder on the server.
<div class="form-group">
<label for="taskName">Feature Image</label>
<InputFile OnChange="HandleFileSelected" />
</div>
#code {
IFileListEntry file;
void HandleFileSelected(IFileListEntry[] files)
{
file = files.FirstOrDefault();
}
async Task CountLines()
{
numLines = 0;
using (var reader = new System.IO.StreamReader(file.Data))
{
while (await reader.ReadLineAsync() != null)
{
numLines++;
}
}
}
async Task UploadFile()
{
if (file != null)
{
var path = System.IO.Path.Combine(Server.MapPath("~/Uploads/"));
string pathstring = System.IO.Path.Combine(path.ToString());
string filename1 = Guid.NewGuid() + System.IO.Path.GetExtension(file.Name);
bool isexists = System.IO.Directory.Exists(path);
if (!isexists)
{
System.IO.Directory.CreateDirectory(pathstring);
}
string uploadpath = pathstring + "\\" + filename1;
file.SaveAs(uploadpath);
}
}
In the code above I have created a UploadFile method and taken my usual way of uploading files, but obviously it wont work because IFileListEntry does not have the SaveAs method and Server will not work on Blazor.
How am I best uploading this file to the server please? (UploadFile method will get called on form submit).

how to pass posted file using ajax beginform in mvc?

I have following in my partial view.
#using (Ajax.BeginForm("xyz", "xyz", new AjaxOptions { HttpMethod = "POST" }, new { enctype = "multipart/form-data" }))
{
<input type="file" name="FileName" id="FileName" style="width:240px" />
<input type="submit" value="Upload" onclick="submit()" />
}
in my controller following is method.
[HttpPost]
//[ValidateAntiForgeryToken]
public JsonResult xyz(HttpPostedFileBase FileName)
{
var httpPostedFileBase = Request.Files["FileName"];
if (httpPostedFileBase != null && httpPostedFileBase.ContentLength > 0)
{
string extension = System.IO.Path.GetExtension(httpPostedFileBase.FileName);
string path1 = string.Format("{0}/{1}", Server.MapPath("~/SavedFiles"), extension);
if (System.IO.File.Exists(path1))
System.IO.File.Delete(path1);
httpPostedFileBase.SaveAs(path1);
}
ViewData["Status"] = "Success";
return Json("test", JsonRequestBehavior.AllowGet);
}
From the above i should get the file on my controller that is posted but it does not give me file instead gives null on controller action.
Please suggest.

unable to upload file on server "Error 500 Inter server Error"

I am stuck in upload file it works fine on local but when I deploy on server it show
500 internal server Error..
Here its my code please review..where m wrong?
Here's my controller code
[HttpPost]
public ActionResult GlovalValues(Global_values REC, HttpPostedFileBase uploadFile)
{
string strPath = "~/Laptop_File/";
string Server_path = "";
string GetFileName = "";
int id = REC.ID;
string Desc = REC.GS_Desc;
string Name = REC.GS_Name;
string values = REC.GS_Values;
int Effrows = 0;
if (uploadFile != null && uploadFile.ContentLength > 0)
{
try
{
if (!Directory.Exists(Server.MapPath(strPath)))
{
DirectoryInfo di = Directory.CreateDirectory(Server.MapPath(strPath));
}
if (Request.Files.Count > 0)
{
var file = Request.Files[0];
var filePath = Request.FilePath;
var FileExtension = uploadFile.FileName.Substring(uploadFile.FileName.LastIndexOf('.') + 1).ToLower();
string ActualFileName = uploadFile.FileName;
GetFileName = Path.GetFileNameWithoutExtension(uploadFile.FileName);
if (file != null && file.ContentLength > 0)
{
string UploadFileName = Path.GetFileName(GetFileName + "." + FileExtension);
Server_path = Path.Combine(Server.MapPath("~/Laptop_File/"), UploadFileName);
if (FileExtension == "xlsx" || FileExtension == "xltx" || FileExtension == "xls" || FileExtension == "xlt ")
{
file.SaveAs(Server_path);
}
}
}
}
catch (Exception ex)
{
throw;
}
}
return RedirectToAction("Global_Values_List", "GS_Global_Values");
}
here's my view
#using (Html.BeginForm("GlovalValues", "GS_Global_Values", FormMethod.Post, new { #id = "id", #enctype = "multipart/form-data" }))
{
<div class="form-group">
<label> Uplaod File : </label>
<div class="col-md-10">
<input type="file" name="uploadFile" id="fileupload" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
Please help I cant figure out whats wrong
In my case it reason from permission.When I ran my project locally on IIS Express everything was fine,and I could upload files correctly, but when I deployed it on IIS 8,it had returned me "Error 500 Internal server Error" for file uploading.
I have changed the permissions for "IIS_IUSRS" on "upload" folder in IIS 8 as follows:
now it is working fine.
Check on server that your application pool has rights of network services or other user with higher authority to Modify the directory & file writing.
If your code is working in local this seems the only issue at moments.

How to upload file of p:fileUpload using command button instead of upload button

Iam using JSF2.1 along with primefaces for uploading file.In my application i have to add the file dynamically on creating a record.But when i use
i cant write the code for uploading my file during save.I want the file to be uploaded on click of save only and not during upload.
Can anyone help me how to implement this
public String handleFileUpload(FileUploadEvent event) throws IOException {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
UploadedFile file = event.getFile();
String prefix = FilenameUtils.getBaseName(file.getFileName());
String suffix = FilenameUtils.getExtension(file.getFileName());
String path = "C:/apache-tomcat-7.0.47/webapps/ROOT/WEB-INF/images";
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File fileToDirectory = File.createTempFile(prefix + "-", "." + suffix, new File(path));
InputStream inputStream = event.getFile().getInputstream();
String fileName = event.getFile().getFileName();
OutputStream outputStream = new FileOutputStream(fileToDirectory);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = inputStream.read(buffer)) > 0){
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
return path+fileName;
}
I need to have this code on save but i cant get event during save
That isn't possible with auto mode. Use the basic mode instead. Then you can bind the input value to an UploadedFile property directly. This only requires disabling Ajax.
E.g.
<h:form enctype="multipart/form-data">
...
<p:fileUpload mode="simple" value="#{bean.file}" />
...
<p:commandButton value="Save" action="#{bean.save}" ajax="false" />
</h:form>
with
private UploadedFile file; // +getter+setter
public void save() {
try (InputStream input = file.getInputStream()) {
// ...
}
}
The alternative is to migrate to standard JSF <h:inputFile> component which was introduced in JSF 2.2. Then you can continue using Ajax.
E.g.
<h:form enctype="multipart/form-data">
...
<h:inputFile value="#{bean.file}" />
...
<p:commandButton value="Save" action="#{bean.save}" />
</h:form>
with
private Part file; // +getter+setter
public void save() {
try (InputStream input = file.getInputStream()) {
// ...
}
}
See also:
How to upload file using JSF 2.2 <h:inputFile>? Where is the saved File?