Unable to Delete record from database using MVC 4 - asp.net-mvc-4

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

Related

Submit button is submitting but not saving - MVC

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")

CRUD Operations in ASP.NET MVC 4

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.

Can you tell me why no file is uploaded, I only get the filename i the tabel?

Can you tell me why no file is uploaded, I only get the filename i the tabel ?
I dont get any errors message, all information is loaded okay in DB ?
I'am using LINQ to SQL MVC4
Table id - CompanyNameCon - PdfCon
Controller:
[HttpPost]
public ActionResult Create(DAT_SupplyCon DAT_SupplyCon, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
DAT_SupplyCon.PdfCon = FileUpload.UploadFile(file);
db.DAT_SupplyCons.InsertOnSubmit(DAT_SupplyCon);
db.SubmitChanges();
return RedirectToAction("Index");
}
return View(DAT_SupplyCon);
}
view
#model CFire2.Models.DAT_SupplyCon
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Html.BeginForm("Create", "DAT_SupplyCons", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>DAT_SupplyCon</legend>
<div class="editor-label">
#Html.LabelFor(model => model.SupplierCon)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SupplierCon)
#Html.ValidationMessageFor(model => model.SupplierCon)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CompanyNameCon)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.CompanyNameCon)
#Html.ValidationMessageFor(model => model.CompanyNameCon)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PdfCon)
</div>
<div class="editor-field">
<input type="file" name="file" />
#Html.ValidationMessageFor(model => model.PdfCon)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Utils:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace CFire2.Utils
{
public static class FileUpload
{
public static char DirSeparator =
System.IO.Path.DirectorySeparatorChar;
public static string FilesPath = "Content" +
DirSeparator + "Uploads" + DirSeparator;
public static string UploadFile(HttpPostedFileBase file)
{
if (null == file) return "";
if (!(file.ContentLength > 0)) return "";
string fileName = file.FileName;
string fileExt = Path.GetExtension(file.FileName);
if (null == fileExt) return "";
if (!Directory.Exists(FilesPath))
{
Directory.CreateDirectory(FilesPath);
}
string path = FilesPath + DirSeparator + fileName;
file.SaveAs(Path.GetFullPath(path));
return fileName;
}
public static void DeleteFile(string fileName)
{
if (fileName.Length == 0) return;
string path = FilesPath + DirSeparator + fileName;
if (File.Exists(Path.GetFullPath(path)))
{
File.Delete(Path.GetFullPath(path));
}
}
}
}
Maybe Server.MapPath is the solution. Example:
var path = Path.Combine(HttpContext.Current.Server.MapPath("~/Content"), fileName);
file.SaveAs(path);

How to upload Photos/ Images in Asp.Net 4.o Project

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

My MVC Controller is not getting the right values from Html.dropdownlist

I'm developing a MVC application.
I had 2 controllers, one for creating Risks and one for creating Tests.
I had to first create a Risk and when I created a Test, I had to use the created Risk as a field of the new Test. I had a dropdownlist to choose from.
Now I'm supposed to create both in the same page because one Test will have one Risk, ie, when I create one Test, I have to create its own Risk, which belongs to that Test and can not be used by any other Test. Business rules.
So, I created a new model with both Test and Risk, changed the model for the create page, included the Risk creation in the create page.
Ok, it seems to work fine, but all the dropdownlists lose their value when I go back to the control. Everything else works fine, except for that.
Here's my model
using CTTModel;
namespace MvcApplication1.ViewModels
{
public class CreateTestWithRisk
{
public Test Tests { get; set; }
public Risk Risks { get; set; }
}
}
The funny thing is that if I try use this model in the first version, Risks and Tests created apart, it works with Risks and not with Tests, meaning that all dropdownlists in Risks return the value and in Tests creation, they don't. Strange.
Here is the code from the controller
//
// GET: /Test/Create
public ActionResult Create()
{
// Risk
ViewBag.SubProcessId = new SelectList(_db.SubProcesses, "Id", "Name");
ViewBag.RiskSeverityId = new SelectList(_db.RiskSeverities, "Id", "Name");
ViewBag.RiskFrequencyId = new SelectList(_db.RiskFrequencies, "Id", "Name");
ViewBag.RiskRatingId = new SelectList(_db.RiskRatings, "Id", "Name");
ViewBag.RiskType1Id = new SelectList(_db.RiskType1, "Id", "Name");
ViewBag.RiskType2Id = new SelectList(_db.RiskType2, "Id", "Name");
// Test
ViewBag.RegionLevelId = new SelectList(_db.RegionLevels, "Id", "Name");
return View();
}
//
// POST: /Test/Create
[HttpPost]
public ActionResult Create(CreateTestWithRisk test)
{
if (ModelState.IsValid)
{
_db.Risks.Add(test.Risks);
Risk iD = _db.Risks.OrderByDescending(id => id.Id).FirstOrDefault();
if (iD != null)
{
test.Tests.RiskId = iD.Id;
test.Tests.Risk = test.Risks;
}
_db.Tests.Add(test.Tests);
_db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.RegionLevelId = new SelectList(_db.RegionLevels, "Id", "Name");
//ViewBag.RiskId = new SelectList(_db.Risks, "Id", "Name", test.Tests.RiskId);
ViewBag.SubProcessId = new SelectList(_db.SubProcesses, "Id", "Name");
ViewBag.RiskSeverityId = new SelectList(_db.RiskSeverities, "Id", "Name");
ViewBag.RiskFrequencyId = new SelectList(_db.RiskFrequencies, "Id", "Name");
ViewBag.RiskRatingId = new SelectList(_db.RiskRatings, "Id", "Name");
ViewBag.RiskType1Id = new SelectList(_db.RiskType1, "Id", "Name");
ViewBag.RiskType2Id = new SelectList(_db.RiskType2, "Id", "Name");
return View(test);
}
And here's part of teh code from the view
#model MvcApplication1.ViewModels.CreateTestWithRisk
#{
ViewBag.Title = "Create New Test";
}
<h2>
Create New Test</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div style="display:inline-block">
<fieldset style="float:left">
<legend>Test</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Tests.RegionLevelId, "RegionLevel")
</div>
<div class="editor-field">
#Html.DropDownList("RegionLevelId", String.Empty)
#Html.ValidationMessageFor(model => model.Tests.RegionLevelId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Tests.Code)
</div>
<div class="editor-field">
</div>
<div>
#Html.EditorFor(model => model.Tests.Code)
#Html.ValidationMessageFor(model => model.Tests.Code)
</div>
</fieldset>
<fieldset style="float:left;margin-left:10px">
<legend>Risk</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Risks.SubProcessId, "SubProcess")
</div>
<div class="editor-field">
#Html.DropDownList("SubProcessId", String.Empty)
#Html.ValidationMessageFor(model => model.Risks.SubProcessId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Risks.RiskSeverityId, "Severity")
</div>
<div class="editor-field">
#Html.DropDownList("RiskSeverityId", String.Empty)
#Html.ValidationMessageFor(model => model.Risks.RiskSeverityId)
</div>
</fieldset>
</div>
<p>
<input type="submit" value="Create" />
</p>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I would have left this as a comment if I had enough rep. However, as a shot in the dark as an answer:
Is your controller properly passing the CreateTestWithRisk model to the View? I.e. are you still using the TestController and expecting it to use the new model? Difficult to see because you don't specify the Controller name, etc. in your question.
This would explain why no data of type CreateTestWithRisk is being passed back to the controller.