I want to add upload photo features in my MVC 4.0 Project, Please can you tell me how can I do that. I am using MVC 4.o and for Photo option i want to give file / image upload. Here is my Code
#model WebCart.Category
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create", "Category", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Category</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</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.Photo)
</div>
<div class="editor-field">
<input name="PhotoFile" id="File" type="file"/>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(Category category)
{
if (ModelState.IsValid)
{
db.Categories.AddObject(category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(category);
}
Your controller action could take an additional PhotoFile argument:
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(Category category, HttpPostedFileBase photoFile)
{
if (ModelState.IsValid)
{
// you could manipulate the PhotoFile parameter here
// for example let's store the uploaded file to a folder on the server
if (photoFile != null && photoFile.ContentLength > 0)
{
var fileName = Path.GetFileName(photoFile.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data"), fileName);
photoFile.SaveAs(path);
}
db.Categories.AddObject(category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(category);
}
Or if you want to read the uploaded file as a byte array you could use the following:
byte[] photo = new byte[photoFile.InputStream.Length];
photoFile.InputStream.Read(photo, 0, photo.Length);
// Now you could assign the byte array to some property of your model
// and persist it into the database (even if this is a bad practice -
// it would be more correct to store the photo on the file system and
// only store the full path to the photo in the database)
A must read article for uploading files in ASP.NET MVC is the following: http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx
Related
My Entity Framework passes a string like this to the database "1b2ef80d-038a-49d8-973b-fc783a53b6a3" instead of the text i placed into the input field, which was "text". How can i only Insert the exact value into the table?
The Database table i'm currently testing is just one column and is set to VARCHAR(400).
Context class:
modelBuilder.Entity<Contract>(entity =>
{
entity.HasKey(e => e.Contract1)
.HasName("Contract$PrimaryKey");
entity.Property<string>(e => e.Contract1)
.HasColumnName("Contract")
.HasColumnType("VARCHAR(400)")
.IsUnicode(false)
.HasMaxLength(400);
});
Model class:
[Key]
[Column(TypeName = "VARCHAR(400)")]
[StringLength(400)]
public string Contract1 { get; set; }
View page:
<form asp-action="Create">
<div class="form-horizontal">
<h4>Contract</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
#Html.LabelFor(model => model.Contract1, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.EditorFor(model => model.Contract1)
#Html.ValidationMessageFor(model => model.Contract1)
<span class="text-danger"></span>
</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>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
</body>
</html>
And Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Contract")] Contract Contract)
{
if (ModelState.IsValid)
{
_context.Add(Contract);
await _context.SaveChangesAsync();
return RedirectToAction("Create");
}
ViewData["Contract"] = new SelectList(_context.Contract, "Contract", "Contract", Contract.Contract1);
return View(Contract);
}
}
}
i had to add the class, instead of just the context.Add i had to make it context.class.Add:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Contract Contract)
{
if (ModelState.IsValid)
{
_context.Contract.Add(Contract);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewData["Contract"] = new SelectList(_context.Contract, "Contract", "Contract", Contract.Contract1);
return View(Contract);
}
}
}
The submit button doesn't go to the post method in the controller. Help please, I am new to programming in ASP.Net and I am trying to debug why the submit button doesn't go the the post method in the controller.
We also are trying to use web services
Here is the code for the Account/View/Login.cshtml
#using WebApplication3.Models
#model LoginViewModel
#{
ViewBag.Title = "Log in";
}
<h2>#ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Use a local account to log in.</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
<p>
#Html.ActionLink("Register as a new user", "Register")
</p>
#* Enable this once you have account confirmation enabled for password reset functionality
<p>
#Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>*#
}
</section>
</div>
<div class="col-md-4">
<section id="socialLoginForm">
#Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is the partial code for the controller
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var RenewalClient = this.RenewalClient.ServiceClient;
bool isValidUser= RenewalClient.ValidateUser(model.Email,model.Password);
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
Your html seems to be fine. It is always good to pass any information using anonymous function as last argument in BeginForm("Login","Account",FormMethod.Post, new {}).
Check whether your controller action is decorated with [HttpPost] attribute because if this attribute is not present on the action method, it will serve only GET request.
I have tried many things to get the submit button to submit to the database. I'm not getting any errors, and the two error messages for testing, one from the controller, one from the view, are not printing to let me know that it is not working. Upon user hitting submit, it renders and displays the same button- Set Statement, instead of the new text that the user entered. Not sure how to fix or where the problem is.
Here is the code:
Controller:
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Create(TableA Statement)
{
var model = new Test.Models.Tables();
using (var db = new Entities())
if (ModelState.IsValid)
{
TableA tablea = new TableA();
tablea.Statement = model.Statement;
db.TablesA.Add(tablea);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return Content("Failed");
}
}
Main View:
<td>
#if (tablea.Statement != null)
{
#Html.DisplayFor(modelItem => tablea.Statement)
<text>|</text>
#Html.ActionLink("Edit", "Edit", new { id = tablea.ID })
}
else
{
Html.RenderAction("PopUp");
var model = new Test.Models.Tables();
if (model.Statement != null) {
<text>Save Successful!</text>
}
}
</td>
Popup View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
=
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Statement, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Statement)
#Html.ValidationMessageFor(model => model.Statement)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" onsubmit="Create(Statement)" class="btn btn-default">
</div.. etc>
Popup View is a partial view or what?, I recommend convert it to partial view, and in your controller you can do something like
public ActionResult CreatePartial()
{
var pages = pageRepository.Pages;
return PartialView(pages);
}
and in your view use
#{Html.RenderAction("Popup", "CreatePartial");}
if your model of partial is different of model of main view, if not use:
#Html.RenderPartial("ViewName")
I have to make a ASP.NET MVC 4 Page which contains Customer details.
One form I have to create in which I have to perform Customer Create, Update and Delete.
The different fields are..
1) Customer ID
2) Customer Name
3) Customer Image
4) Customer Address
Now, I am confused with Customer Image. How to store Image in database and how to display it in Gridview from database. Please solve my problem as it's very important for me..
As #LajosArpad said save image as file and only save path of the image in database.
Here is view for creating customer
<div class="box box-primary">
#using (Html.BeginForm("Create", "Customer", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal box-body">
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Image</label>
<div class="col-md-10">
<input class="form-control" name="image" type="file" />
</div>
</div>
</div>
<div class="box-footer">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
}
</div>
And controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = "Id")] Customer customer, HttpPostedFileBase image)
{
if (ModelState.IsValid)
{
if (image != null && image.ContentLength > 0)
{
var filePath = GetFilePath(image.FileName);
image.SaveAs(filePath);
customer.ImageUrl = "~/images/upload/" + Path.GetFileName(filePath);
}
// Save customer to database
return RedirectToAction("Index");
}
return View(news);
}
// Get absolute path for saving image and check it does not exist
public static string GetFilePath(string fileName)
{
var targetFolder = System.Web.Hosting.HostingEnvironment.MapPath("~/images/upload/");
var targetPath = Path.Combine(targetFolder, fileName);
if (File.Exists(targetPath))
{
var name = Path.GetFileNameWithoutExtension(fileName);
name = name + "-" + (new Random()).Next();
var extension = Path.GetExtension(fileName);
name = name + extension;
GetFilePath(name);
}
return targetPath;
}
You store the image as a file and you store the path of the image in the database. If I were you I would generate the filenames instead of using the original filenames to make sure they are not duplicated. So you do not need to store the images in the database, you can store them as separate files.
I am trying to delete data using MVC in my application. For this first I am fetching the records from the database into the labels. Then I am trying to delete this. The code which I am writing is below
This is the code of my Controller
public ActionResult Delete(string id)
{
DBData dbData = new DBData();
StudentData sd = new StudentData();
DataSet ds;
ds = dbData.SelectUserById(id);
sd.SID = Convert.ToInt32(ds.Tables[0].Rows[0]["sid"].ToString());
sd.StudentName = ds.Tables[0].Rows[0]["studentname"].ToString();
sd.ContactNo = ds.Tables[0].Rows[0]["contactno"].ToString();
sd.EmailId = ds.Tables[0].Rows[0]["emailid"].ToString();
return View(sd);
}
[HttpPost]
public ActionResult Delete(StudentData sd)
{
if (ModelState.IsValid)
{
DBData db = new DBData();
db.DeleteRecord(sd);
return RedirectToAction("SelectAllStudent", "Student");
}
else
{
ModelState.AddModelError("", "Error while Deleting data");
return View();
}
}
Here is my model
public void DeleteRecord(StudentData sd)
{
SqlConnection con = new SqlConnection();
try
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
if (con.State == ConnectionState.Closed)
{
con.Open();
}
SqlCommand cmd = new SqlCommand("delete from studentinfo where sid=#sid", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#sid", sd.SID);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch
{
}
finally
{
con.Close();
}
}
as you see StudentData is a class in which I define properties.
Now here is my View
#model CrudMVC.Models.StudentData
#{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>StudentData</legend>
<div class="display-label">
#Html.DisplayNameFor(model => model.SID)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.SID)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.StudentName)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.StudentName)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.EmailId)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.EmailId)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.ContactNo)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.ContactNo)
</div>
</fieldset>
#using (Html.BeginForm()) {
<p>
<input type="submit" value="Delete" /> |
#Html.ActionLink("Back to List", "SelectAllStudent")
</p>
}
Now when I am trying to delete my record everytime,not a single record was deleted .I add breakpoint and check the values. But In HttpPost function StudentData sd had not any single value. Its show me null.Why these properties are empty I dnt know. Please experts Help me to get out of this error
You do not have any inputs within you form element to post back (note Html.DisplayFor() methods do not render html inputs)
#using (Html.BeginForm()) {
#Html.EditorFor(model => model.SID)
#Html.EditorFor(model => model.StudentName)
// Other properties here
<input type="submit" value="Delete" />
}
If you don't want editable fields you can create hidden inputs for all properties or consider just posting back the ID and modifying you controller action