I have this controller and what I am trying to do is to send an image to the controller as a [byte], this is my controller:
[HttpPost]
public ActionResult AddEquipment(Product product, HttpPostedFileBase image)
{
if (image != null)
{
product.ImageMimeType = image.ContentType;
product.ImageData = new byte[image.ContentLength];
image.InputStream.Read(product.ImageData, 0, image.ContentLength);
}
_db.Products.Add(product);
_db.SaveChanges();
return View();
}
and on my view:
#using (Html.BeginForm("AddEquipment", "Equipment", FormMethod.Post)) {
<fieldset>
<legend>Product</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<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>
<div class="editor-label">
#Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Price)
#Html.ValidationMessageFor(model => model.Price)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Category)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Category)
#Html.ValidationMessageFor(model => model.Category)
</div>
<div>
<div>IMAGE</div>
<input type="file" name="image" />
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
but the problem is that on my controller the value for image is alway null, I cant seem to get any information on the HttpPostedFileBase
You need to add the encType with multipart/form-data.
#using (Html.BeginForm("AddEquipment", "Equipment", FormMethod.Post, new {enctype = "multipart/form-data" })) {
You can always add it to your model too as follows, providing it is a ViewModel:
public class Product
{
public Product()
{
Files = new List<HttpPostedFileBase>();
}
public List<HttpPostedFileBase> Files { get; set; }
// Rest of model details
}
You can the retrieve the files by removing the un-needed parameter i.e.
[HttpPost]
public ActionResult AddEquipment(Product product)
{
var file = model.Files[0];
...
}
Try to do this at the top of the Action method:
[HttpPost]
public ActionResult AddEquipment(Product product, HttpPostedFileBase image)
{
image = image ?? Request.Files["image"];
// the rest of your code
}
And the form should have enctype of "multipart/form-data" to upload files:
#using (Html.BeginForm("AddEquipment", "Equipment", FormMethod.Post, new {enctype = "multipart/form-data" })) {
Related
Basically i have created a mvc application that will be performing CRUD operations on the database data using entity framework generated from database edmx.So in this after adding EDM and configuring database settings i've added a controller named CRUD with scaffolding enabled to read/write action views and attached model and DB conttext to it.Now everything works as desired upto the point of adding new employee ie Create.The problem comes when i run the index page of crud controller and in which when i press the actionlink edit or delete for any specific employee data it doesn't find that Edit and Delete cshtml pages at all and instead shows the error 404 resource not found.Please help me figure out what's wrong,i'm posting my whole code below:
public class CRUDController : Controller
{
private TestDBEntities2 db = new TestDBEntities2();
public ActionResult Index()
{
return View(db.Emps.ToList());
}
public ActionResult Details(int id = 0)
{
Emp emp = db.Emps.Find(id);
if (emp == null)
{
return HttpNotFound();
}
return View(emp);
}
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Emp emp)
{
if (ModelState.IsValid)
{
db.Emps.Add(emp);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(emp);
}
public ActionResult Edit(int id = 0)
{
Emp emp = db.Emps.Find(id);
if (emp == null)
{
return HttpNotFound();
}
return View(emp);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Emp emp)
{
if (ModelState.IsValid)
{
db.Entry(emp).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(emp);
}
public ActionResult Delete(int id = 0)
{
Emp emp = db.Emps.Find(id);
if (emp == null)
{
return HttpNotFound();
}
return View(emp);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Emp emp = db.Emps.Find(id);
db.Emps.Remove(emp);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
Index.cshtml
#model IEnumerable<MvcApplication2.Emp>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.EmployeeID)
</th>
<th>
#Html.DisplayNameFor(model => model.Firstname)
</th>
<th>
#Html.DisplayNameFor(model => model.Lastname)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
<th>
#Html.DisplayNameFor(model => model.Project)
</th>
<th>
#Html.DisplayNameFor(model => model.Address)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.EmployeeID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Firstname)
</td>
<td>
#Html.DisplayFor(modelItem => item.Lastname)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /*id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
Create.cshtml
#model MvcApplication2.Emp
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Emp</legend>
<div class="editor-label">
#Html.LabelFor(model => model.EmployeeID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmployeeID)
#Html.ValidationMessageFor(model => model.EmployeeID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Firstname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Firstname)
#Html.ValidationMessageFor(model => model.Firstname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Lastname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Lastname)
#Html.ValidationMessageFor(model => model.Lastname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Age)
#Html.ValidationMessageFor(model => model.Age)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Project)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Project)
#Html.ValidationMessageFor(model => model.Project)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Edit.cshtml
#model MvcApplication2.Emp
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Emp</legend>
<div class="editor-label">
#Html.LabelFor(model => model.EmployeeID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmployeeID)
#Html.ValidationMessageFor(model => model.EmployeeID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Firstname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Firstname)
#Html.ValidationMessageFor(model => model.Firstname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Lastname)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Lastname)
#Html.ValidationMessageFor(model => model.Lastname)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Age)
#Html.ValidationMessageFor(model => model.Age)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Project)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Project)
#Html.ValidationMessageFor(model => model.Project)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Image of Solution Explorer:
pass EmployeeID in your ActionLinks:
#Html.ActionLink("Edit", "Edit", new {id=item.EmployeeID }) |
#Html.ActionLink("Details", "Details", new {id=item.EmployeeID }) |
#Html.ActionLink("Delete", "Delete", new {id=item.EmployeeID })
try to add the Controller Name
#Html.ActionLink("Edit", "Edit", "CRUD", new {/*id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", "CRUD", new { /*id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", "CRUD", new { /*id=item.PrimaryKey */ })
My Controller
[HttpGet]
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(Customers Customer)
{
if (ModelState.IsValid)
{
_db.Customers.Add(Customer);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(Customer);
}
My Model:
public class Customers
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set;}
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
// public ICollection<CustomerData> Customers { get; set; }
}
From my View:
<p>
#Html.ActionLink("Create New", "Create")
Create.cshtml:
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Add New Customer</legend>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.State)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.State)
#Html.ValidationMessageFor(model => model.State)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Zip)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Zip)
#Html.ValidationMessageFor(model => model.Zip)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Phone)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Phone)
#Html.ValidationMessageFor(model => model.Phone)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
When I run this code, all of the fields end up getting rendered from the subsequent Create.cshtml. Filling in all of the forms and clicking the submit button sends me back to "Index", but does not add any of my fields into the database. It seems like the Create action is not being hit. Anyone have any advice for a beginner?
First off, thanks for everyone responding so quickly. Turns out, I had my db set to deploy on debug somehow. When I unchecked deploy on my project debug properties, everything worked.
Is there a way to check in a helper/extension method if a certain script is present in a view?
My idea is to create a custom TextBoxFor() method where the focus is moved to the next input once the present one reach the maxLenght.
why don't you just use javascript for this task?
Example:
http://www.aspdotnet-suresh.com/2013/02/javascript-automatically-move-cursor-to.html
You have JQuery AutoTab Plugin - http://autotab.mathachew.com/
Download the AutoTab Min JS - https://github.com/Mathachew/jquery-autotab/blob/master/js/jquery.autotab.min.js
Lets say I have a model -
public class Details
{
public string Name { get; set; }
public string Email { get; set; }
}
now create a view -
#model YourNameSpave.Details
#{
ViewBag.Title = "GetData";
}
<h2>GetData</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Details</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Name, new { #class = "alphanumeric", maxlength = 10})
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Email, new { #class = "alphanumeric", maxlength = 10})
#Html.ValidationMessageFor(model => model.Email)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.autotab.min.js"></script>
<script>
$(function () {
$('.alphanumeric').autotab();
});
</script>
And now you will get autotab functionality as you wished.
Application View:
#model Models.ApplicationModel
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.SectionID);
#Html.HiddenFor(m => m.CurrentSectionName);
<div class="section" id="Terms">
#Html.EditorFor(m => m.Term)
</div>
<div class="section" id="User">
#Html.EditorFor(m => m.User)
</div>
<input type="submit" value="Save" />
}
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$('form').click(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
debugger;
}
});
}
return false;
});
});
</script>
Application Model:
public class ApplicationModel
{
public int SectionID;
public Term Term;
public User User;
public string CurrentSectionName;
}
Application Controller:
public ActionResult Save(ApplicationModel ApplicationModel, FormCollection fc)
{
return PartialView("Application", ApplicationModel);
}
/EditorTemplates/Term:
#model Data.Term
<fieldset>
<legend>Term</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Type)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Type)
#Html.ValidationMessageFor(model => model.Type)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Length)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Length)
#Html.ValidationMessageFor(model => model.Length)
</div>
</fieldset>
/EditorTemplates/User:
#model Data.User
<fieldset>
<legend>User</legend>
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MiddleInitial)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MiddleInitial)
#Html.ValidationMessageFor(model => model.MiddleInitial)
</div>
</fieldset>
When I click the save button, in the Application Controller, only the FormCollection has keys (21 of them). The model is not bound with data.
What am I doing wrong here?
Try this, Add {get; set;} to your model
public class ApplicationModel
{
public int SectionID {get; set;}
public Term Term {get; set;}
public User User {get; set;}
public string CurrentSectionName {get; set;}
}
You may also need to check the access modifier on your Model's properties. I ran into this same situation and while I had setters on my properties, they were protected instead of public. Thank you to Mate for pointing me in the right direction as well.
I'm pretty sure this is because the form only POSTS inputs when submitting a form, no?
So when I recieve a POST response, the name I edited is correctly received but the ID is always set to 0.
Any workarounds?
public ActionResult Edit(int id)
{
var productBrand = brandRepo.FindProductBrand(id);
ProductBrandModel model = Mapper.Map<ProductBrand, ProductBrandModel>(productBrand);
return View(model);
}
[HttpPost]
public ActionResult Edit(ProductBrandModel model)
{
if (ModelState.IsValid)
{
var productBrand = brandRepo.FindProductBrand(model.ProductBrandId);
productBrand.Name = model.Name;
brandRepo.SaveChanges();
return RedirectToAction("Index", "ProductBrands");
}
return View(model);
}
/* THIS IS THE VIEW*/
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>ProductBrandModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ProductBrandId)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.ProductBrandId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
I don't want to let the users edit the ID of the entity, only the name.
Thank you.
What about adding
#Html.HiddenFor(model => model.ProductBrandId)
I think that will do what you want, if I understand your question.