File upload not working as expected - asp.net-mvc

I am trying to upload a file from my application and it is not working as expected. I am not getting any file into the action method.
I have my viewmodel as below
public class CallQueryViewModel
{
[Display(Name = "Attachment")]
public HttpPostedFileBase UploadFile { get; set; }
}
And my Razor form is as below
#{
var ajaxOptions = new AjaxOptions
{
HttpMethod = "POST",
OnBegin = "onCallAddBegin",
OnSuccess = "OnCallCreateSuccess",
OnFailure = "OnCallCreateFailure"
};
}
#using (Ajax.BeginForm("AddCall", "CallHandling", ajaxOptions, new { #id = "CallAddForm", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="row">
<div class="col-md-6">
<div class="form-group">
#Html.LabelFor(model => model.UploadFile, new { #class = "col-md-2" })
#Html.TextBoxFor(model => model.UploadFile, new { #class = "col-md-10", type="file" })
</div>
</div>
</div>
<div id="Submit">
<input type="submit" value="Save" class="btn btn-success" />
</div>
}
And my controller action method is as below.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddCall(CallQueryViewModel model)
{
if ((model.UploadFile != null) && (model.UploadFile.ContentLength > 0))
{
// Upload file.
}
}
With the above code, when i am trying to upload the file, I am not receiving any file into the controller action method. The UploadFile is always coming as null.
Could someone suggest what I am missing ?

Related

Image upload using #Ajax.BeginForm in .NET MVC?

I want to upload image using Ajax.BeginForm in my application.
Currently HttpPostedFileBase file is getting value 0. Anyone Please guide me here.
I have tried this code but file is not uploading.
Appreciated, if anyone can provide some solutions for this. If I use #Html.BeginForm then It works but I want to use #Ajax.BeginForm.
Model
public class ClsUpload
{
public string FilePath { get; set; }
}
Controller
public ActionResult Edit(ClsUpload model,HttpPostedFileBase file)
{
if (Request.Files.Count > 0)
{
file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
string fileName = Path.GetFileName(file.FileName);
string path = Path.Combine(Server.MapPath("/Content/Images/"), fileName);
file.SaveAs(path);
model.FilePath = path;
}
}
try
{
UploadDetials details = new UploadDetials();
details.UpdateDetails(model);
return RedirectToAction("Index");
}
catch
{
return RedirectToAction("Index");
}
}
Partial View
#model XX.X.Models.File.ClsUpload
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "partial", InsertionMode = InsertionMode.Replace }))
{
#Html.HiddenFor(model => model.FilePath)
<input type="file" name="file" />
<img src=#Model.FilePath alt="Image" />
<input type="submit" value="Save" />
}
You can update your code with FormMethod.Post, new { enctype = "multipart/form-data" }) and [AcceptVerbs(HttpVerbs.Post)] as follow
In Partial View
#using (Html.BeginForm("ActionMethod1", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
In Controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ActionMethod1(HttpPostedFileBase pic)
{
}
This is old, but I want to show how I have accomplished uploading a file using Ajax.BeginForm(). Basically, the overloads will tell you what is possible. I use the overload for: "string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes". Note: I use null for "routeValues".
Here is a code example:
#using (Ajax.BeginForm("UploadFile", "Home", null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "MyIDToUpdate", OnSuccess = "EditSuccessClearForm('IDToClear', '')", OnFailure = String.Format("NewGenericFailure(xhr, '{0}')", "#IDToPassThisFunction"), InsertionMode = InsertionMode.ReplaceWith }, new { enctype = "multipart/form-data", #id = "NewFileFormID" }))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-sm-8 col-sm-offset-1">
#Html.TextBox("file", "", new { type = "file", accept = ".jpg, .jpeg, .png, .pdf", #id = fileID, onchange = VerifySizeOfFile })
</div>
<div class="col-sm-2">
<button type="submit" id="FileSubmitButton" class="btn btn-primary">Upload</button>
</div>
</div>
}

MVC Error on Displaying Data From Web API

I am new to ASP.NET programming and I encounter some problem, maybe someone can help me to find the solution.
I followed and completed the procedure here BeginForm with IEnumerable. But when I tried to run my codes. Something error happens on browser. The error is:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ek_oms.Models.AddCategoryViewModel]', but this dictionary requires a model item of type 'ek_oms.Models.AddCategoryViewModel'.
Here's my related codes to that part.
Class:
public class AddCategoryViewModel
{
public IEnumerable<CategoryViewModel> CurrentCategories { get; set; }
public CategoryModel NewCategory { get; set; }
}
Partial codes in View:
#model ek_oms.Models.AddCategoryViewModel
#if (Model.CurrentCategories != null)
{
foreach (var item in Model.CurrentCategories)
{
<tr>
<td>#item.CategoryName</td>
<td>
#using (Html.BeginForm("CategoryDelete", "Admin", new { catID = item.Id }, FormMethod.Post, null))
{
#Html.AntiForgeryToken()
#Html.ActionLink("Edit", "CategoryEdit", null, new { catID = item.Id }, new { #class = "btn btn-primary btn-xs" })
<button type="submit" class="btn btn-danger btn-xs" onclick="return confirm('Are you sure you want to delete record with Category = #item.CategoryName')">Delete</button>}
</td>
</tr>
}
}
<div class="tab-content">
#using (Html.BeginForm("Categories", "Admin", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { role = "form" }))
{
#Html.AntiForgeryToken()
<div class="box box-primary">
<!-- /.box-header -->
<div class="box-body">
<div class="box-header">
<h3 class="box-title">Add New Category</h3>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
#Html.EditorFor(model => model.NewCategory.CategoryName, new { htmlAttributes = new { #class = "form-control", id = "Category", #placeholder = #Html.DisplayNameFor(model => model.NewCategory.CategoryName) } })
#Html.ValidationMessageFor(model => model.NewCategory.CategoryName, "", new { #class = "text-danger" })
</div>
<div class="form-group">
</div>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary" id="submitAddCatBtn">Add</button>
</div>
</div>
}
</div>
Controller:
public async Task<ActionResult> Categories()
{
ViewBag.Message = TempData["Message"];
ViewBag.CatUsedMessage = TempData["CatUsedMessage"];
HttpResponseMessage responseMessage = await client.GetAsync(urlProducts + "/categories");
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
var categories = JsonConvert.DeserializeObject<List<AddCategoryViewModel>>(responseData);
return View(categories);
}
return View("Error");
}
Can someone help me to this. I don't know the right term to start searching. Thanks.
var categories = JsonConvert.DeserializeObject<List<AddCategoryViewModel>>(responseData);
Above line is the issue.
Your view is expecting just one AddCategoryViewModel object and not a List<AddCategoryViewModel>. As the error message clearly suggests.
So, change your code to return only one object if you are expecting just one from the api as below:
var categories = JsonConvert.DeserializeObject<AddCategoryViewModel>(responseData);
OR if you need more than one category
Change your #model in view as below:
#model List<ek_oms.Models.AddCategoryViewModel>
In this case you will need to change your view code to handle Category list accordingly as below:
#foreach(var cat in Model)
{
if (cat != null)//use cat in place of Model in your view
{
foreach (var item in cat.CurrentCategories)
{
}
}
}

File upload in MVC when used in bootstrap modal returns null

I'm trying to upload images to my application but it always returns null. I'm unable to find the issue here. Can you help me out? Here's my code.
Model
[Table("Slider")]
public partial class Slider : BaseModel
{
[Required]
[StringLength(200)]
public string FileName { get; set; }
[StringLength(200)]
public string Title { get; set; }
[StringLength(1000)]
public string Description { get; set; }
public int? Order { get; set; }
}
[NotMapped]
public class SliderImage : Slider
{
public HttpPostedFileBase ImageFile { get; set; }
}
View
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.FileName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.FileName, new { #class = "form-control", #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.FileName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ImageFile, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.ImageFile, new { #class = "form-control", type = "file" })
//This is Same as below
//<input class="form-control" id="ImageFile" name="ImageFile" type="file" value="">
</div>
</div>
Controller
public ActionResult Edit(int id)
{
Slider slider = _db.Sliders.Find(id);
if (slider == null)
{
return HttpNotFound();
}
Mapper.CreateMap<Slider, SliderImage>();
SliderImage sliderImage = Mapper.Map<Slider, SliderImage>(slider);
return PartialView("_Edit", sliderImage);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditSlider([Bind(Include = "Id,FileName,Title,Description,Order,IsActive,Name,ImageFile")] SliderImage sliderImage)
{
if (ModelState.IsValid)
{
Mapper.CreateMap<SliderImage, Slider>();
Slider slider = Mapper.Map<SliderImage, Slider>(sliderImage);
_db.Entry(slider).State = EntityState.Modified;
_db.SaveChanges();
return Json(new { success = true });
}
return PartialView("_EditSlider");
}
What am I doing wrong i this?
Found The Issue
I'm binding the partial view inside the bootstrap modal popup. When I upload from the popup, the upload returning null. Instead if I open the partial View directly in browser, then the file is present in the model. So there is no problem with file upload. The problem is with modal popup or something.
When Using Bootstrap model
When using partial View Directy
Check the difference found when using fiddler between the Bootstrap Modal Submit and Using the partial View Directly in the following image respectively
When posting from the modal popup, the content type is changed to application/x-www-form-urlencoded where as when using the partial view directly it is multipart/form-data
Found the root Issue.
$('form', dialog).submit(function () {
var $form = $(this);
var enctype = $form.attr('id');
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
//Refresh
location.reload();
} else {
$('#myModalContent').html(result);
bindForm();
}
}
});
return false;
});
I'm using AJAX posting to submit the data from my form. When using $(this).serialize() the ajax success is being called but the file is not returning as the content type is different. How can I change this??
I think I have been able to identify your problem, Ajax does not support file serialization, you should use the following method in the script:
$('form', dialog).submit(function () {
var formData = new FormData($(this)[0]);
$.ajax({
url: this.action,
type: this.method,
contentType: this.enctype,
data: formData,
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
$('#replacetarget').load(result.url); // Load data from the server and place the returned HTML into the matched element
} else {
$('#myModalContent').html(result);
bindForm(dialog);
}
}
});
return false;
});
Ok, I think your current issue is related to the default settings for the jQuery.ajax method. By default, the content type for the jQuery.ajax() method is 'application/x-www-form-urlencoded; charset=UTF-8'. So, in a sample project, I modified your javascript function to specify the contentType as a paramter to the ajax method: contentType: this.enctype
I think there also may be a couple additional issues. The next issue that I noticed is that on submission, I was connecting to another actions, so I updated this line in the view:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
To this:
#using (Html.BeginForm("EditSlider", "<Your Controller Name>", FormMethod.Post, new { enctype = "multipart/form-data" }))
Lastly, when the ajax submitted, I was being redirected to the partial view. I believe this can be fixed by adding preventDefault to the ajax function:
$('form', dialog).submit(function (event) {
event.preventDefault();
var $form = $(this);
$.ajax({
url: this.action,
type: this.method,
contentType: this.enctype,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
//Refresh
location.reload();
} else {
$('#myModalContent').html(result);
bindForm();
}
}
});
});
This is how I was able to get this example working in a sample project; please post an update if you have additional issues.
Usually, modal pop-ups are rendered at the end of the body. I'm pretty sure that bootstrap does the same thing. This, in turn, means that the content of the modal is moved to a new location and is taken out of your form element. I would recommend a reordering: move the form inside the modal window:
<div class="modal-body">
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
...
}
</div>
This will move the entire form (and not just the form elements) when the modal gets built.
Only the file uploaded return null? or the other textbox return null as well?
As #Andrei comments, usually the modals is moved to a new location and the form is not present or your partialview could be moved to make the modal works.
With jqueryUI I had a similar problem. I couldn't find in your question if you are using ajax to submit your data, you could use .ajax() to send your form and see if the image was upload
$.ajax({
url: "#Url.Action("Action", "Controller")",
type: "POST",
cache: false,
data: $("#YourFormID").serialize(),
success: function (result) {
//your success data
},
error: function (jqXHR, textStatus, errorThrown) {
//your error handler
},
});
return false;
If you don't want to use $.ajax(), you could try to use .appendTo() with jquery, wrap everything what it is inside your form in a div with an ID, then after you have all your data try to sepecify that you want to appendTo("#YourFormID") on a button click, or as you like. This work for me when I was using modal, hope it helps you with something. Good luck
If I understand you make the form in a partial View, and this partial is used in a modal popup, it's right.
1) make a model for used in the form with all elements for the form,
2) declare the model in the first line in the partial view
3) pass as parameter the model to the post function.
4) you use a Partial view, well is possible use this view in differents pages, you need specify the control to treatement the form. in code:
MODEL
public partial class SliderModel
{
[Required]
[StringLength(200)]
public string FileName { get; set; }
[StringLength(200)]
public string Title { get; set; }
[StringLength(1000)]
public string Description { get; set; }
public int? Order { get; set; }
[NotMapped]
public HttpPostedFileBase ImageFile { get; set; }
}
VIEW
#model YOURNAMESPACE.Models.SliderModel
<form method="post" class="form-horizontal" role="form" id="sendMail"
enctype="multipart/form-data" action="/CONTROLLERNAME/EditSlider">
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.FileName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.FileName, new { #class = "form-control", #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.FileName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ImageFile, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.ImageFile, new { #class = "form-control", type = "file" })
//This is Same as below
//<input class="form-control" id="ImageFile" name="ImageFile" type="file" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1">
<button type="submit" class="btn btn-success"><b><i class="fa fa-envelope"></i> Envoyer</b> </button>
</div>
</div>
</form>
CONTROLLER
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditSlider(SliderModel obj)
{
if (ModelState.IsValid)
{
your options
}
return PartialView("_EditSlider");
}
Try with following way this worked for me :
VIEW :
#using (Html.BeginForm("ComplaintAndSuggestion", "RegisterComplaints", FormMethod.Post, new { enctype = "multipart/form-data", id = "ajaxUploadForm" }))
{
:
:
:
<div class="row mb10">
<div class="col-sm-3 col-md-3">
<label for="file1">Upload Image 1</label>
<input type="file" name="images" id="file1" accept="image/*" />
</div>
<div class="col-sm-3 col-md-3">
<label for="file2">Upload Image 2</label>
<input type="file" name="images" id="file2" accept="image/*" />
</div>
<div class="col-sm-3 col-md-3">
<label for="file3">Upload Image 3</label>
<input type="file" name="images" id="file3" accept="image/*" />
</div>
<div class="col-sm-3 col-md-3">
<label for="file4">Upload Image 4</label>
<input type="file" name="images" id="file4" accept="image/*" />
</div>
</div>
<input type="submit" value="Create" />
}
Controller :
[HttpPost]
public ActionResult ComplaintAndSuggestion(Register register, IEnumerable<HttpPostedFileBase> images, IEnumerable<HttpPostedFileBase> videos)
{
foreach (var file in images)
{
if (file != null)
{
string filenameWithDateTime = AppendTimeStamp(file.FileName);
file.SaveAs(Server.MapPath(Path.Combine("~/Images/", filenameWithDateTime)));
fileUploadModel.FilePath = (Server.MapPath(Path.Combine("~/Images/", filenameWithDateTime)));
fileUploadModel.FileName = filenameWithDateTime;
fileUploadModel.FileType = "Image";
fileUploadModel.RegisterId = register.RegisterId;
mediaRepository.Add(fileUploadModel);
mediaRepository.Save();
}
}
}
Let me know.

How to display a model state error in case I am returning a partial view

I have the following action method for creating new network info:-
public ActionResult CreateVMNetwork(int vmid)
{
VMAssignIps vmips = new VMAssignIps()
{
TechnologyIP = new TechnologyIP() { TechnologyID = vmid},
IsTMSIPUnique = true,
IsTMSMACUnique = true
};
return PartialView("_CreateVMNetwork",vmips);
}
[HttpPost]
public ActionResult CreateVMNetwork(VMAssignIps vmip)
{
if (ModelState.IsValid)
{
try
{
repository.InsertOrUpdateVMIPs(vmip.TechnologyIP,User.Identity.Name);
repository.Save();
return PartialView("_networkrow",vmip);
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, "Error occurred: " + ex.InnerException.Message);
}
}
return PartialView("_CreateVMNetwork", vmip);
}
And I have the following _CreateVMNetwork view:-
#model TMS.ViewModels.VMAssignIps
#using (Ajax.BeginForm("CreateVMNetwork", "VirtualMachine", new AjaxOptions
{
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "networktable",
LoadingElementId = "loadingimag",
HttpMethod= "POST"
}))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(model=>model.TechnologyIP.TechnologyID)
#Html.Partial("_CreateOrEditVMNetwork", Model)
<input type="submit" value="Save" class="btn btn-primary"/>
}
and _CreateOrEditVMNetwork view:-
#model TMS.ViewModels.VMAssignIps
<div>
<span class="f">IP Address</span>
#Html.EditorFor(model => model.TechnologyIP.IPAddress)
#Html.ValidationMessageFor(model => model.TechnologyIP.IPAddress)
<input type="CheckBox" name="IsTMSIPUnique" value="true" #(Html.Raw(Model.IsTMSMACUnique ? "checked=\"checked\"" : "")) /> |
<span class="f"> MAC Address</span>
#Html.EditorFor(model => model.TechnologyIP.MACAddress)
#Html.ValidationMessageFor(model => model.TechnologyIP.MACAddress)
<input type="CheckBox" name="IsTMSMACUnique" value="true" #(Html.Raw(Model.IsTMSMACUnique ? "checked=\"checked\"" : "")) />
</div>
The problem I am facing is that in case there is a model state error when adding a new entity, a partial view will be displayed with the model state error as follow:-
So my question is , if there is a way to display the model state error with the partial view , without updating the table row “insert after” as I am doing currently?
Thanks
Given the age i'm guessing you have already found a solution to this,
But here is an example using InsertionMode.Replace, maybe it can help someone else.
Snipped from view
#using (Ajax.BeginForm("AddPerson", "Home", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "UpdateSection" }))
{
<div id="UpdateSection">
#Html.Partial("PersonModel", Model.Person)
</div>
<input type="submit" value="add" />
}
Snipped from the controller
if (!ModelState.IsValid)
{
return PartialView("AddPerson", Person);
}
just make sure the "jquery.unobtrusive-ajax.min.js" script is included (i'm not sure it is by default)

HttpPostedFileBase not binding to model

here is my ViewModel
public class FaultTypeViewModel
{
[HiddenInput(DisplayValue = false)]
public int TypeID { get; set; }
[Required(ErrorMessageResourceType = typeof(AdministrationStrings), ErrorMessageResourceName = "FaultTypeNameRequired")]
[Display(ResourceType = typeof(AdministrationStrings), Name = "FaultTypeName")]
public string TypeName { get; set; }
[Display(ResourceType = typeof(AdministrationStrings), Name = "FaultTypeDescription")]
[DataType(DataType.MultilineText)]
public string TypeDescription { get; set; }
[Display(ResourceType = typeof(AdministrationStrings), Name = "FaultTypeImageFile")]
public HttpPostedFileBase TypeImageFile { get; set; }
[HiddenInput(DisplayValue = false)]
public string TypeImageURL { get; set; }
}
Notice I have a "TypeImageFile" HttpPostedFileBase
I would expect that the model binder would bond that property from the form to the model passes to the controller bu I just keep receiving null.
here is the relevant code in the View:
#using (Html.BeginForm("AddFaultType","Administration", FormMethod.Post))
{
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×</button>
<h3 id="myModalLabel">#SharedStrings.Add #SharedStrings.FaultType</h3>
</div>
<div class="modal-body">
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.TypeName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TypeName)
#Html.ValidationMessageFor(model => model.TypeName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TypeDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TypeDescription)
#Html.ValidationMessageFor(model => model.TypeDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TypeImageFile)
</div>
<div class="editor-field">
<input type="file" name="TypeImageFile" id="TypeImageFile" />
</div>
</div>
<div class="modal-footer">
<input type="submit" value="#SharedStrings.Add" class="btn btn-primary" />
#Html.ActionLink(SharedStrings.Cancel, "Index", "Administration", null, new { Class = "btn", data_dismiss = "modal", aria_hidden = "true" })
</div>
}
and here is the controller:
[HttpPost]
public ActionResult AddFaultType(FaultTypeViewModel i_FaultToAdd)
{
var fileName = Path.GetFileName(i_FaultToAdd.TypeImageFile.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
i_FaultToAdd.TypeImageFile.SaveAs(path);
return RedirectToAction("Index");
}
Make sure you've set the enctype attribute on your form to multipart/form-data on your form if you want to be able to upload files:
#using (Html.BeginForm("AddFaultType", "Administration", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}
Completing Darin's answer:
Make sure you've set the enctype attribute on your form to multipart/form-data on your form if you want to be able to upload files:
#using (Html.BeginForm("AddFaultType", "Administration", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}
To ensure your <input> is transmitted to the controller as part of the model use the Html Helpers for Id and name like below:
<input type="file" id="#Html.IdFor(x=>x.HttpPostedFileBase)" name="#Html.NameFor(x=>x.HttpPostedFileBase)" accept=".csv,.txt"/>
Works in MVC5 sorry I cant find any reference to which helpers are available in MVC3

Resources