for some reason, my form post does not work when i have the hidden field in mvc3 razor. It works fine if i remove the hidden field but i need that field.
Below are my ProductsController post method and razor view
#model CCSPurchasing_MVC.Models.AddNewProductModel
#using CCSPurchasing_MVC.Models
#using (Html.BeginForm("editImage", "Products", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(m => m.ImadeId)
<div class="editor-field">
<p style="margin-left: 300px; margin-right: 20px;">
#Html.LabelFor(m => m.ImageFile)
<input type="file" name="file" id="file" data-val="true" data-val-required="Product Image is required"/>
</p>
</div>
<input type="submit" value="Edit" />
}
[HttpPost]
public ActionResult editImage(AddNewProductModel newP, HttpPostedFileBase file)
{
db = new DBConnection();
if (file != null && file.ContentLength > 0)
{
newP.ImageName = Path.GetFileName(file.FileName);
newP.ImageType = file.ContentType;
newP.ImageSize = file.ContentLength;
newP.ImageFile = new byte[file.ContentLength];
file.InputStream.Read(newP.ImageFile, 0, file.ContentLength);
newP.ImageHeight = 200;
newP.ImageWidth = 200;
}
string result = db.editImage(newP);
return View("editImageUpdate");
}
Just make your form tag like this and I am sure it will work for you also as it worked for me when I tested your code:
#using (Html.BeginForm("EditImage", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
You need to add enctype = "multipart/form-data" also in your code if you want to submit the file with your fileupload control.
Related
Ajax form is not submitting to controller action. Here is the code
#using (Ajax.BeginForm("searchCustomers", "Transaction", new { phoneNumber = Model.CustomerMobile }, new AjaxOptions
{
UpdateTargetId = "custList",
InsertionMode = InsertionMode.Replace
}))
{
<div class="col-md-6">
<div class="form-group">
<label>Customer Mobile No:</label>
#Html.TextBoxFor(x => x.CustomerMobile, new { #class = "form-control", id = "custMobile" })
</div>
#*<div class="form-group">
<label>Customer Name</label>
#Html.TextBoxFor(x => x.CustomerName, new { #class = "form-control", id = "custName" })
</div>*#
<input type="submit" class="btn btn-default" value="Get Customer Details" >
</div>
}
Here is the controller action
public ActionResult searchCustomers(string phoneNumber)
{
if (phoneNumber==null)
{
return PartialView(new List<Models.Customer>());
}
var c = Database.Session.Query<Models.Customer>()
.Where(x => x.MobileNumber.Like(phoneNumber) )
.ToList();
return PartialView(c);
}
but the ajax form is not submitting. I've added the JavaScript files as bundles. I've another #Html.Action("searchCustomers", new { phoneNumber = Model.CustomerMobile }) this one calls the controller action.
Everything is fine in your code. There are two javascript files that are needed for Ajax.Beginform to work.
jquery-{Vaersion}.js
jquery.unobtrusive-ajax.js
Check whether you have included those files to your view or not. Or if your view has any LayOut if those javascript files are included in your LayOut or not.
The Ajax form does update selected div, but instead of just reloading a partial view in that div it inserts the whole page content into that div.
.cshtml file
<fieldset>
<legend>File(s)</legend>
<div id="filesBody">
#Html.Action("Action", "Controller", new {id=Model.Id})
</div>
<br />
#using (Ajax.BeginForm("UploadFile", "Controller", null, new AjaxOptions { UpdateTargetId="filesBody"}, new { enctype = "multipart/form-data", #id = "myForm" }))
{
#Html.HiddenFor(model => model.ComplaintId)
<div>
<label for="File">Add File:</label>
<input type="file" name="FileAttachment" />
<input type="submit" value="Upload" />
#Html.ValidationMessage("FileAttachment")
</div>
}
</fieldset>
Controller
public PartialViewResult GetFilesData(long? Id)
{
Model Model = new Model(Id);
TryUpdateModel(Model);
return PartialView(Model);
}
Partial view
#model Models
<div id="reloadField">
#foreach (var ph in Model.docs)
{
///code
}
</div>
In your partial view set the Layout equal to null.
#model Models
#{
Layout = null;
}
UPDATE
Change your Ajax.BeginForm to call the GetFilesData action.
I'm working on an app on ASP.Net MVC 4 and am trying to upload an image in a form. The problem I'm having is that when the form posts, if the <input type="file"... is empty (meaning I have not selected a file) the form posts just fine and everything works. However, When I do select a file the form just sits there and does nothing.
At first I thought it was just taking it a while to upload but I have left it for quite some time (file size was 7kb) and nothing. the debugger doesn't even hit the breakpoints at the beginning of the action either. I'm at a loss since I'm quite new to the platform and am still learning every day. Below please find all the relevant code:
the View:
#using (Html.BeginForm("StaffInformation", "Manager", FormMethod.Post, new { #class = "form-horizontal", enctype = "multipart/form-data"}))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="control-group">
#Html.LabelFor(model => model.firstName, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(model => model.firstName, new { #class = "span12" })
#Html.ValidationMessageFor(model => model.firstName)
</div>
</div>
<div class="control-group">
#Html.LabelFor(model => model.lastName, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(model => model.lastName, new { #class = "span12" })
#Html.ValidationMessageFor(model => model.lastName)
</div>
</div>
<div class="control-group">
Staff Photo:
<div class="controls">
#if (Model.staffImage == null)
{
#:None
}else{
<img width="150" height="150" src="#Url.Action("GetImage", "Manager", new { Model.staffProfileID })" /><br />
}
<input type="file" id="staffImage" name="staffImage" data-provide="fileinput">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save changes</button>
<a href="#Url.Action("dashboard", "manager")" class="btn" type="reset" >Cancel</a>
</div>
}
The Action:
public ActionResult StaffInformation(StaffInformationViewModel model, HttpPostedFileBase staffImage)
{
if (ModelState.IsValid) //This is where the breakpoint is
{
if (staffImage != null) {
model.imageMimeType = staffImage.ContentType;
model.staffImage = new byte[staffImage.ContentLength];
staffImage.InputStream.Read(model.staffImage, 0, staffImage.ContentLength);
}
using (var repo = new CompanyInformationRepository(new UniteOfWorkCompanies()))
{
var company = repo.FindCompany(User.Identity.Name);
repo.AddOrUpdateStaff(model, company);
}
return RedirectToAction("ManageStaff");
}
}
I really don't know whats going on and simply the reason I'm using the enctype = "multipart/form-data" is because I was reading the "Pro ASP.NET MVC 4" by Adam Freeman and in there they said that it won't work without it. Like I said, I'm quite new and need all the help I can get.
You can try to put the HttpPostedFileBase staffImage as part of your ViewModel (StaffInformationViewModel) - also yes, you need to keep the enctype = "multipart/form-data" in the form tag:
public class StaffInformationViewModel
{
// your other properties here ...
[Required]
public HttpPostedFileBase StaffImage { get; set; }
}
Then in the View:
#Html.TextBoxFor(model => model.StaffImage, new { type = "file" })
Then in the Controller:
public ActionResult StaffInformation(StaffInformationViewModel model)
{
if (ModelState.IsValid)
{
if (model.StaffImage != null)
{
// awesome
}
// ... more awesome
}
}
I hope this helps. Let me know if you need more clarifications here on this one ...
Had this working; at one stage. The problem is the following text is now appearing in the field for the image in the database "System.Web.HttpPostedFileWrapper"
the following code is from the controller:
[HttpPost]
public ActionResult Create(CarAdvert caradvert,
HttpPostedFileBase picture1)
{
if (ModelState.IsValid)
{
if (picture1 != null)
{
string image1 = picture1.FileName;
caradvert.Image1 = image1;
var image1Path = Path.Combine(Server.MapPath("~/Content/Images"), image1);
picture1.SaveAs(image1Path);
}
db.CarAdverts.Add(caradvert);
db.SaveChanges();
return RedirectToAction("Index");
}
This code is from the create view:
#using (Html.BeginForm("Create", "UserCarAdverts", FormMethod.Post, new { enctype = "multipart/form-data" })) {
#Html.ValidationSummary(true)
<fieldset>
<legend>CarAdvert</legend>
<div class="editor-field">
<input type="file" name="Image1" />
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
the paramater in the controller for HttpPostedFileBase has to have the same name as the input type="file" . Either do:
[HttpPost]
public ActionResult Create(CarAdvert caradvert,
HttpPostedFileBase Image1)
or
<input type="file" name="picture1" />
That should do it
i have a create view to add answers to a question, currently the user can only add one answer at the same time when he clicks on the submit button, instead of this i want the user to be able to insert multiple answers objects into the same view and then the system to add all these new answer objects to the database after the user click on the submit button, my current view looks as the follow:-
#model Elearning.Models.Answer
#{
ViewBag.Title = "Create";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div id = "remove">
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "remove"
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</fieldset>
<input type= "hidden" name = "questionid" value = #ViewBag.questionid>
<input type= "hidden" name = "assessmentid" value = #ViewBag.assessmentid>
<input type="submit" value="Add answer" />
</div>
}
</div>
and the action methods look as the follow:-
public ActionResult Create(int questionid)//, int assessmentid)
{
ViewBag.questionid = questionid;
Answer answer = new Answer();
return PartialView("_answer",answer);
}
//
// POST: /Answer/Create
[HttpPost]
public ActionResult Create(int questionid, Answer a)
{
if (ModelState.IsValid)
{
repository.AddAnswer(a);
repository.Save();
return PartialView("_details",a);
}
return View(a);}
so how i can modify the above code to be able to insert multiple answer objects at the same view and then submit these answers objects at the same time when the user click on the submit button?
Try Post a List
Add input by javascript when user click "Add Answer".
And when submit the form ,it will post all answer data to binding to List
<script>
$(document).ready(function () {
var anwserCount = 1;
$("#addbutton").click(function () {
$("#AnwsersDiv")
.append("<input type='text' name='Anwsers[" + anwserCount + "]'/>");
anwserCount += 1;
});
});
</script>
#using (Html.BeginForm())
{
<div id="AnwsersDiv">
<input type="text" name="Anwsers[0]" />
</div>
<input id="addbutton" type="button" value="Add answer" />
<input type="submit" value="submit" />
}
Model
public class Answer
{
public List<String> Anwsers { get; set; }
}
When submit the form
I think this is what you are looking for
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Conclusion: you should make the post action with ICollection<Answer> Parameter, then it will be easy to get them when you post your main form, and create the appropriate QUESTION object, then save them all with only one submit.