ASP .NET MVC uploaded file is always null - c#

I'm trying to upload a JSON file, but the MVC controller is always interpreting it as null.
View:
<h3>OR</h3><br>
#Html.TextBox("jsonFile", null, new { type = "file" })
<div class="col-md-offset-2 col-md-10 ">
<input type="submit" value="Create" class="btn btn-default submit-button" formaction="Create" />
</div>
Controller:
public ActionResult Create(HttpPostedFileBase jsonFile)
{
MessageBox.Show("Create");
String str;
if (ModelState.IsValid)
{
if (jsonFile != null)
{
MessageBox.Show("File Upload Success");
StreamReader jsonReader = new StreamReader(jsonFile.InputStream);
str = jsonReader.ReadLine();
MessageBox.Show(str);
}
else
{
MessageBox.Show("Null");
}
return RedirectToAction("Index");
}
return View(projectDetail);
}
Its the part of bigger program and I have used following code for form:
#using (Html.BeginForm( new { htmlAttributes = new { enctype = "multipart/form-data" } } ))
{
}
I get this button to upload files and file upload is also working well as I can see its uploaded status before I click Submit. Not sure why it's always null in the controller.

Have you decorated your action method with "HTTPPOST" attribute? I can't see that in your create action.
public ActionResult Create(HttpPostedFileBase jsonFile)
And also you have to update your form as blow to have controller and action method.
#using (Html.BeginForm("Create", "ControllerName", FormMethod.Post, new { id = "FormCreate", enctype = "multipart/form-data"}))

Related

Controller action not grabbing file from view when attempting to upload

I am trying to upload a .csv file into an SQL database, but the controller action does not seem to be grabbing the file at all. Check out the code, I must be missing a piece:
View:
#using (Html.BeginForm("UploadValidationTable", "Home", FormMethod.Post))
{
<table style="margin-top: 150px;">
<tr>
<td>
<label for="csvFile">Filename:</label>
</td>
<td>
<input type="file" name="csvFile" id="csvFile"/>
</td>
<td><input type="submit" value="Upload"/></td>
</tr>
</table>
}
Controller:
[HttpPost]
public JsonResult UploadValidationTable(HttpPostedFileBase csvFile)
{
var inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
var cc = new CsvContext();
var filePath = uploadFile(csvFile.InputStream);
var model = cc.Read<OutstandingCreditCsv>(filePath, inputFileDescription);
try
{
var entity = new OutstandingCreditCsv();
foreach (var item in model)
{
entity.PoNumber = item.PoNumber;
entity.CreditInvoiceDate = item.CreditInvoiceDate;
entity.CreditInvoiceNumber = item.CreditInvoiceNumber;
entity.CreditInvoiceAmount = item.CreditInvoiceAmount;
}
}
catch(LINQtoCSVException ex)
{
}
return Json(model, "text/json");
}
csvFile is just appearing as null, no clue what could be going on since it is named in the view and I have the post method surrounding it. It makes it down until var filePath = uploadFile(csvFile.InputStream); and then breaks since the method is trying to pass a null value. Thanks!
I came across this when trying to upload files into db using MVC a while back, I was using scaffolded views (so it also passed back an object with the form), so it might be a bit different.
In your HTML.BeginForm() call you'll need to add the attribute enctype="multipart/form-data"
#using (Html.BeginForm("UploadValidationTable", "Home", FormMethod.Post, new {enctype="multipart/form-data"}))
I think you need to add enctype='multipart/form-data' to your <form>
using (Html.BeginForm("UploadValidationTable", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
You need to change your form declaration. Try adding enctype = "multipart/form-data" to your form declaration.
#using (Html.BeginForm("UploadValidationTable", "Home", FormMethod.Post, new { enctype = "multipart/form-data"}))
You need to add the following to the form declaration:
#using (Html.BeginForm("UploadValidationTable", "Home", null,FormMethod.Post, new { enctype = "multipart/form-data" }))

Save Image Using Ajax.BeginForm in MVC 4

I'm trying to Save Image Using Ajax form. But Unable to Get uploaded image in my action.
This is my Index Page, In this page I'm loading partialview for Add Item .
My Index.Cshtml
#Html.Action("_AddOrUpdateItem","Admin")
My Action Code
public PartialViewResult _AddOrUpdateItem(int? itemId)
{
//Some Code Here
return PartialView("_AddItem", item);
}
[HttpPost]
public PartialViewResult AddOrUpdateItem(ToolItem toolItem, HttpPostedFileBase toolItemImage)
{
////Some Code Here
return PartialView("_AddItem", toolItem);
}
}
And My ajax form is as follow
#using (Ajax.BeginForm("AddOrUpdateItem", "Admin", new AjaxOptions() { HttpMethod = "POST" }, new { enctype = "multipart/form-data" }))
{
// Some more text boxes here
<input type="file" id="ToolItemImage" name="toolItemImage" />
<input type="submit" value="Save" />
}
I got a link for this same type of problem , But In my case it is not working
Upload file using Ajax form
It's impossible load file using only Ajax.BeginForm without additional js script,which have been provided in your link and I can't see it in your code.Anyway I strongly recommend use Jquery Form Plugin for such purposes.
I dont know ASP MVC but for submitiing a form with file you have to use enctype="multipart/form-data">
so your form must be having something like this
<form action"your controller" method="post" enctype="multipart/form-data">
<input type="file" id="ToolItemImage" name="toolItemImage" />
<input type="submit">
</form>
Save Ajax.Begien Form Image save this Jquery method and also check validation your form using ($("#frmUploader").valid()) this line of code ...
#using (Ajax.BeginForm("Create", "Employee", new AjaxOptions()
{
OnBegin = "startBLoading",
OnComplete = "stopBLoading",
OnSuccess = "OnSuccessI"
}, new { enctype = "multipart/form-data", id = "frmUploader" }))
{
<div class=row>
..... Enter the Page View Desgine.....
<button type="submit" class="btn btn-product text-capitaliz">Create</button>
</div>
}
<script type="text/javascript">
window.addEventListener("submit", function (e) {
debugger
if ($("#frmUploader").valid()) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (form.dataset.ajaxUpdate) {
var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
if (updateTarget) {
updateTarget.innerHTML = xhr.responseText;
}
}
}
};
xhr.send(new FormData(form)
);
}
}
OnSuccessI();
} else {
e.preventDefault();
}
},
true
);
</script>

FileUpload: keep filenames when showing validation errors

I have the following file-upload code in C# using Asp.Net MVC. The problem is that when validation errors are shown, all the files chosen by the user are lost (input boxes are cleared). Is it possible to keep the input filenames in their original ordering without using javascript? What's the simplest approach?
Controller code
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files)
{
//check for errors: if errors, ModelState.AddModelError(...);
if (!ModelState.IsValid) {
return View(files);
}
else {
//..........
}
}
View snippet
#using (Html.BeginForm("Index", "Uploader", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<input type="file" name="files" id="file1" />
#Html.ValidationMessage("1")
</div>
<div class="form-group">
<input type="file" name="files" id="file2" />
#Html.ValidationMessage("2")
</div>
//and 2 more file input fields
<div>
<input type="submit" value="Upload Files" class="btn btn-success btn-lg" />
</div>
}
In postback you can not retain same local path which will remain in type="file".
to do this think there are two way
1) in your current code if you find any file attached then save on server and maintain some flag in hidden field and hide/show your file control with text box( having only filename)
and send it back to browser. Then on next valid submit take that file name that you have already saved. and do your process.
2) On submit of form, copy(DOM copy) all your html control(file ,textbox, hidenfield ect..) in one iframe and submit that iframe.
In case anybody is still in search of a possibility, here is the work around that worked for me. I'm using MVC5. The idea is to use a session variable. I got the idea from ASP.Net Form.
My Model/ViewModel (only relevant properties):
public partial class emp_leaves
{
public string fileNameOrig { get; set; }
public byte[] fileContent { get; set; }
public HttpPostedFileBase uploadFile { get; set; }
}
In my controller (HttpPost):
//Check
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(emp_leaves emp_leaves)
{
if (emp_leaves.uploadFile != null && emp_leaves.uploadFile.ContentLength>0 && !string.IsNullOrEmpty(emp_leaves.uploadFile.FileName))
{
emp_leaves.fileNameOrig = Path.GetFileName(emp_leaves.uploadFile.FileName);
emp_leaves.fileContent = new byte[emp_leaves.uploadFile.ContentLength];
emp_leaves.uploadFile.InputStream.Read(emp_leaves.fileContent, 0, emp_leaves.uploadFile.ContentLength);
Session["emp_leaves.uploadFile"] = emp_leaves.uploadFile; //saving the file in session variable here
}
else if (Session["emp_leaves.uploadFile"] != null)
{//if re-submitting after a failed validation you will reach here.
emp_leaves.uploadFile = (HttpPostedFileBase)Session["emp_leaves.uploadFile"];
if (emp_leaves.uploadFile != null && emp_leaves.uploadFile.ContentLength>0 && !string.IsNullOrEmpty(emp_leaves.uploadFile.FileName))
{
emp_leaves.fileNameOrig = Path.GetFileName(emp_leaves.uploadFile.FileName);
emp_leaves.uploadFile.InputStream.Position = 0;
emp_leaves.fileContent = new byte[emp_leaves.uploadFile.ContentLength];
emp_leaves.uploadFile.InputStream.Read(emp_leaves.fileContent, 0, emp_leaves.uploadFile.ContentLength);
}
}
//code to save follows here...
}
Finally within my edit view: here, i am conditionally showing the file upload control.
< script type = "text/javascript" >
$("#removefile").on("click", function(e) {
if (!confirm('Delete File?')) {
e.preventDefault();
return false;
}
$('#fileNameOrig').val('');
//toggle visibility for concerned div
$('#downloadlrfdiv').hide();
$('#uploadlrfdiv').show();
return false;
}); <
/script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
#model PPMSWEB.Models.emp_leaves #{ HttpPostedFileBase uploadFileSession = Session["emp_leaves.uploadFile"] == null ? null : (HttpPostedFileBase)Session["emp_leaves.uploadFile"]; } #using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data"
})) { #Html.AntiForgeryToken()
<div class="row">
#*irrelevant content removed*#
<div id="downloadlrfdiv" #((!String.IsNullOrEmpty(Model.fileNameOrig) && (Model.uploadFile==n ull || uploadFileSession !=null)) ? "" : "style=display:none;")>
<label>Attachment</label>
<span>
<strong>
<a id="downloadlrf" href="#(uploadFileSession != null? "" : Url.Action("DownloadLRF", "emp_leaves", new { empLeaveId = Model.ID }))" class="text-primary ui-button-text-icon-primary" title="Download attached file">
#Model.fileNameOrig
</a>
</strong>
#if (isEditable && !Model.readonlyMode)
{
#Html.Raw("&nbsp");
<a id="removefile" class="btn text-danger lead">
<strong title="Delete File" class="glyphicon glyphicon-minus-sign"> </strong>
</a>
}
</span>
</div>
<div id="uploadlrfdiv" #(!(!String.IsNullOrEmpty(Model.fileNameOrig) && Model.uploadFile==n ull) && !Model.readonlyMode ? "" : "style=display:none;")>
<label>Upload File</label> #Html.TextBoxFor(model => model.uploadFile, new { #type = "file", #class = "btn btn-default", #title = "Upload file (max 300 KB)" }) #Html.ValidationMessageFor(x => x.uploadFile)
</div>
</div>
}

Text response displayed in a view's unbound label

I have a view that contains a submit button. When that submit button is clicked some code runs a process. I want to return a text message to a label on the view that will let the user know that their submission was successful or there was an error.
I've searched around and I have found many examples about labels but I haven't come across one that shows me how to do what I want.
My Controller:
public ActionResult Import()
{
//Some code that runs a process
//Need to know what code will return "Import was Successful" or "Erroring Importing"
return RedirectToAction("Import")
}
My View:
#{
ViewBag.Title = "Import";
}
<h2>Import</h2>
#using (Html.BeginForm("Importexcel", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table>
<tr><td>Import Files</td><td><input type="file" id="FileUpload1" name="FileUpload1" /></td></tr>
<tr><td></td><td><input type="submit" id="Submit" name="Submit" value="Submit" /></td></tr>
**<tr><td>#Html.Label(returned results)</td></tr>** // Need to know how to do this
</table>
}
In your view:
#using (Html.BeginForm("Importexcel", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table>
<tr><td>Import Files</td><td><input type="file" id="FileUpload1" name="FileUpload1" /></td></tr>
<tr><td></td><td><input type="submit" id="Submit" name="Submit" value="Submit" /></td></tr>
**<tr><td>#Html.Label(returned results)</td></tr>** // Need to know how to do this
</table>
#ViewBag.Message
}
In your controller:
[HttpPost]
public ActionResult Import(){
//Some code that runs a process
//Need to know what code will return "Import was Successful" or "Erroring Importing"
if(something){
ViewBag.Message = "Import Failed";
}
else
{
ViewBag.Message = "Import Successful";
}
return View();
}
Try and give that a shot.
You can always pass either a key to a look-up table of messages or the message itself via the query string. Here's an example:
Controller Action
public ActionResult Import(string message = null)
{
// Detect presence of message (i.e. !String.IsNullOrWhiteSpace(message)) and show it.
// Additional logic after this...
return RedirectToAction("Import", "YourControllerNameHere", new { message = "Your message here..." });
}
Then it's just a matter of wiring up your model or ViewModel in the Import view so it displays the appropriate message.

HttpPostedFileBase always returns null

I am using MVC 4 and I tried for upload file concept.
Here is my code:
<div class="complianceSubDiv">
<div class="complianceLeftDiv">
#Html.Label("Upload the file")
</div>
<div class="complianceRightDiv">
<input type="file" id="file" name="file" />
</div>
</div>
My controller code like
[HttpPost]
public ActionResult ManageDocument(DocumentModel documentModel, HttpPostedFileBase file)
{
//some code
}
But the HttpPostedFileBase file always returns null. I have searched more answers in StackOverflow and other websites and I got the working answer is parameter of HttpPostedFileBase variable name and fileupload control name are same . So I put the same name on all sides, but it returns null only.
Anyone help to me?
Finally i got it
Now i replaced for #using (Html.BeginForm())
to
#using (Html.BeginForm("ManageDocument", "Document", FormMethod.Post, new { enctype = "multipart/form-data" }))
It's working !
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase myFile)
{
myFile = Request.Files["file"];
if (myFile != null && myFile.ContentLength > 0)
{
// your code ....
}
return View();
}
You can use "Request.Files" to get the selected file, above is the code.

Categories

Resources