ASP.NET MVC 4 data access - sql-server

I am trying to show the employee details in a table. I created a model class EmployeeDetail, an EmployeeController and a view in EmployeeDetails.cshtml, plus a class for accessing the database.
EmployeeDetails is my model class:
[Serializable]
public class EmployeeDetails
{
private int _eid;
private string _ename;
private string _eaddress;
private string _gender;
private string _emobileno;
private bool _status;
private DateTime _ejoiningdate;
private DateTime _eleavedate;
#region ================= Code start for public variable =========================
[DataObjectField(true,true,false)]
public int eid {
get { return _eid; }
set { _eid = value; }
}
[DataObjectField(true, true, false)]
public string ename
{
get { return _ename; }
set { _ename = value; }
}
[DataObjectField(true, true, false)]
public string eaddress
{
get { return _eaddress; }
set { _eaddress = value; }
}
[DataObjectField(true, true, false)]
public string gender
{
get { return _gender; }
set { _gender = value; }
}
[DataObjectField(true, true, false)]
public string emobileno
{
get { return _emobileno; }
set { _emobileno = value; }
}
[DataObjectField(true, true, false)]
public bool status
{
get { return _status; }
set { _status = value; }
}
[DataObjectField(true, true, false)]
public DateTime ejoiningdate
{
get { return _ejoiningdate; }
set { _ejoiningdate = value; }
}
[DataObjectField(true, true, false)]
public DateTime eleavedate
{
get { return _eleavedate; }
set { _eleavedate = value; }
}
#endregion ==================== code end for public variable =================
}
Here is my EmployeeController:
public class EmployeeController : Controller
{
// GET: /Employee/
private Employeecon db = new Employeecon();
public ActionResult EmployeeDetails()
{
var studentList = new List<EmployeeDetails>{
new EmployeeDetails() { eid = 1, ename = "John", eaddress = "teszxs" } ,
new EmployeeDetails() { eid = 2, ename = "Steve", eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 3, ename = "Bill", eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 4, ename = "Ram" , eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 5, ename = "Ron" , eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 4, ename = "Chris" , eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 4, ename = "Rob" , eaddress = "jfdsk" }
};
return View();
}
}
I created EmployeeDetails.cshtml as a Razor view:
#model IEnumerable<Employee.Models.EmployeeDetails>
<html>
<head>
<title>Employee Details</title>
</head>
<body>
<div align="center">
<b> Employee Details</b>
</div>
<div align="right">
<p>
#Html.ActionLink("New Employee", "NewEmployee")
</p>
</div>
<table align="center" cellpadding="5" cellspacing="5" style="border:1px thin
black;" frame="box">
<tr>
<th>
Name
</th>
<th>
Address
</th>
<th>
Mobile no
</th>
<th>
Joining Date
</th>
</tr>
#foreach(var r in Model)
{
<tr>
<td>
#* #r.ename;*#
#Html.DisplayNameFor(m => r.ename); //but when I am declaring like that its showing error the call is ambiguous between the following methods or properties
</td>
</tr>
<tr>
<td>
#*#r.eaddress;*#
#Html.DisplayNameFor(m => r.eaddress);
</td>
</tr>
<tr>
<td>
#* #r.emobileno;*#
#Html.DisplayNameFor(m => r.emobileno);
</td>
</tr>
<tr>
<td>
#* #r.ejoiningdate;*#
#Html.DisplayNameFor(m => r.ejoiningdate);
</td>
</tr>
}
</table>
</body>
</html>
I am creating a separate folder for data access. I created a data context file Employeecon.cs:
public class Employeecon : DbContext
{
public Employeecon() : base("EmployeeContext")
{
}
public DbSet<EmployeeDetails> emp { get; set; }
}
And I added a connection string to the web.config file:
<add name="EmployeeContext"
connectionString="Data Source=LEVIOZA;Initial Catalog=Manali;Persist Security Info=True;User ID=sa;Password=pedcall"
providerName="System.Data.SqlClient" />
I want to connect to a SQL Server database, instead of local db, or I don't want to create database in the App_Data folder. Like we are did in the asp.net using SQL Server we pass the connection string using SqlConnection like that.
I am trying to connect but I don't know if it's working or not .
I don't know whats wrong with this program. I am trying to learn ASP.NET MVC and this is my first try. Please help me.

So you actually did a good job so far, let me point you to the rest.
Firstly, with database connection a side, you did created a simulation of data, which i assume you wonder why they did not shown in the view.
This is because you did not asked the controlled to use your data as model for the view. Yes, you did specify which type the model is, but you didn't supply it with data.
To fix it, pass the View() method the model instance you want, so it can bind it together.
return View(studentList);
Secondly, you want to extract those information from database, you only lacking querying the information you want from database and return it as model.
For example, lets create another url called /EmployeeDetailsFromDb
public ActionResult EmployeeDetailsFromDb()
{
var studentList = db.EmployeeDetails; // .EmployeeDetails should be changed to the table\dataset you want.
return View(studentList);
}
This will work, assuming the EmployeeDetails(if exists) is actually a collection of EmployeeDetails entities, which is what the view .cshtml expects.

Related

Asp.net core database data displayed more often than existing

I'm wondering why my ASP.NET Core MVC Project is listing my data double.
What it should be:
What it gives me:
See the difference?
My Controller (Controller Class - Index()-Method):
[HttpGet()]
public async Task<IActionResult> Index(string id)
{
IQueryable<string> werkeQuery = from m in _context.TestDbSet
orderby m.Id
select m.Id;
var test = from t in _context.TestDbSet
orderby t.Id
select t;
if (!string.IsNullOrEmpty(id))
{
test = (IOrderedQueryable<TestSet>)_context.TestDbSet.Where(x => x.Id == id);
}
var filter = new TestSet
{
Werke = new SelectList(await werkeQuery.Distinct().ToListAsync()),
Liste = await test.ToListAsync()
};
return View(filter);
}
My Model-Class (could there be the error?):
`[Table("Test", Schema = "dbo")]
public class TestSet
{
[Key]
[Display(Name = "Werk")]
[Column("Id")]
public string Id { get; set; }
[Display(Name = "Mitarbeiter ID")]
[Column("M_ID")]
public string M_Id { get; set; }
[Column("Beginn")]
[DataType(DataType.Date)]
public DateTime Beginn { get; set; }
[Column("Ende")]
[DataType(DataType.Date)]
public DateTime Ende { get; set; }
[NotMapped]
public SelectList Werke { get; set; }
[NotMapped]
public List<TestSet> Liste { get; set; }
}`
My View (relevant code: displayed list):
`#model DienstplanAnzeige.Models.TestSet
#{
ViewData["Title"] = "Startseite";
}
<form asp-controller="Home" asp-action="Index" method="get">
<div class="input-group mb-3">
<select class="custom-select" asp-for="Id" asp-items="#Model.Werke">
<option value="" disabled selected>Werk auswählen</option>
</select>
<input type="submit" value="Anzeigen" class="btn btn-outline-secondary" />
</div>
</form>
<table class="table table-hover">
<thead>
<tr>
<th>#Html.DisplayNameFor(model => model.Liste[0].Id)</th>
<th>#Html.DisplayNameFor(model => model.Liste[0].M_Id)</th>
<th>#Html.DisplayNameFor(model => model.Liste[0].Beginn)</th>
<th>#Html.DisplayNameFor(model => model.Liste[0].Ende)</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model.Liste)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Id)</td>
<td>#Html.DisplayFor(modelItem => item.M_Id)</td>
<td>#Html.DisplayFor(modelItem => item.Beginn)</td>
<td>#Html.DisplayFor(modelItem => item.Ende)</td>
</tr>
}
</tbody>
</table>`
My Context-Class (named "TestContext"):
public class TestContext : DbContext
{
public TestContext(DbContextOptions<TestContext> options)
: base(options)
{
}
public DbSet<TestSet> TestDbSet { get; set; }
}
Can someone help me?
In your controller, since your id property and parameter is in string therefore instead of using == comparison operator you should use Equals(...) method of string class i.e.
if (!string.IsNullOrEmpty(id))
{
test = (IOrderedQueryable<TestSet>)_context.TestDbSet.Where(x => x.Id.Equals(id, StringComparison.InvariantCultureIgnoreCase);
}

Displaying the result set of a Db view in asp.net core view

I am executing a stored procedure from my asp.net core app. The procedure executes a select statement from a db view. The db view inner joins 3 tables. When I execute the following code the result set comes as an int throwing an exception as the razor view expects List, I need to receive it as a list in order to pass it to the razor view and display the table. I would appreciate any help.
ViewModel:
public class ViewModel
{
public int TimeKey { get; set; }
public int FiscsalYear { get; set; }
public string LocationNum { get; set; }
public string Location { get; set; }
}
View:
#model List<FactWorkOrdersViewModel>
#{
ViewBag.Title = "Stored Procedure Test";
}
<div class="container">
<table class="table table-hover">
<thead>
<tr>
<th colspan="5"><h3>Stored Procedures results</h3></th>
</tr>
<tr>
<th>TimeKey</th>
<th>Fiscal Year</th>
<th>Location Number</th>
<th>Location</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#item.TimeKey
</td>
<td>
#item.WorkOrderAltKey
</td>
<td>
#item.FiscsalYear
</td>
<td>
#item.LocationNum
</td>
<td>
#item.Location
</td>
</tr>
}
</tbody>
</table>
<div>
Controller:
public IActionResult SPTest(ReportViewModel model)
{
DbConnection connection = db.Database.GetDbConnection();
using (DbCommand cmd = connection.CreateCommand())
{
cmd.CommandText = "ExecuteReport";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#ReportId", model.ID));
if (connection.State.Equals(ConnectionState.Closed))
{
connection.Open();
}
var result = cmd.ExecuteScalar();
//var result = cmd.ExecuteNonQuery();
if (connection.State.Equals(ConnectionState.Open))
{
connection.Close();
}
return View(result);
}
This is a possible duplicate.
Please refer to What is the difference between ExecuteScalar, ExecuteReader and ExecuteNonQuery? for more information.
Short answer : You need ExecuteReader not ExecuteScalar.
ExecuteScalar returns first column's value of first row. ExecuteReader will return the list of rows which we can iterate through and display on your page.
I figured it out, thanks #Amogh
public IActionResult SPTest(ReportViewModel model)
{
List<ViewModel> viewModel = new List<ViewModel>();
using (SqlConnection conn = new SqlConnection("server=ServerName;database=DBName; user id=user_id; password=password; MultipleActiveResultSets=true"))
{
conn.Open();
SqlCommand cmd = new SqlCommand("ExecuteReport", conn)
{
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.Add(new SqlParameter("#ReportId", model.ID));
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
foreach (var item in rdr)
{
ViewModel vm = new ViewModel
{
TimeKey = (int)rdr.GetValue(0),
FiscsalYear = (int)rdr.GetValue(2),
LocationNum = (string)rdr.GetValue(5),
Location = (string)rdr.GetValue(6)
};
viewModel.Add(vm);
}
}
}
}
return View(viewModel);
}

How to display image in list in MVC?

I'm a final year student, working on FYP, I have an issue about fetching image that is stored in binary data in database. I tried lots of solutions, I've searched on Google, but not working any solution.
View
#model IEnumerable<PictureServices.Picture>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
<tr>
#foreach (var item in Model)
{
<td>
#{
var base64 = Convert.ToBase64String(item.image);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
}
<img src='#imgsrc' style="max-width:100px; max-height:100px;">
</td>
model
public class Picture
{
public int id { get; set; }
public byte[] image { get; set; }
public string name { get; set; }
}
controller
public class CarServicesController : Controller
{
TestingEntities db = new TestingEntities();
public ActionResult Index()
{
Picture ds = new Picture();
var item = (from d in db.Pictures
select d).ToList();
return View(item);
}
You can convert the byte array to base 64 string and use that as the image source. You can use the Convert.ToBase64String to do so. One thing you must do is a null check before trying to convert the byte array as that could be null.
#model IEnumerable<PictureServices.Picture>
<table class="table table-striped">
#foreach (var r in Model)
{
<tr>
<td>#r.Id</td>
<td>#r.Name</td>
<td>
#if (r.Image != null)
{
var imgSrc = $"data:image/jpg;base64,{Convert.ToBase64String(r.Image)}";
<img src="#imgSrc" alt="#r.Name" />
}
</td>
</tr>
}
</table>
I would also recommend using PascalCasing for C# class properties ( Name instead of name).

How to display/store and retrieve image as varbinary(MAX) using ASP.NET MVC view

I am new to ASP.NET MVC, so kindly excuse for mistakes.
I need a view page (index.cshtml) where I can display the image, change/delete the image by storing it in Varbinary(max) column in a SQL Server table.
There are these columns in the database table:
ID int primary key Identity not null,
ImageName nvarchar(50) ,
ImagePicInBytes varbinary(MAX) null
I am using a Image.cs with this code:
public class Image
{
public int ID {get; set;}
public string ImageName {get; set;}
public byte[] ImagePicInBytes {get; set;}
}
ImageContext class as below
public class ImageContext : DbContext
{
public DbSet<Image> Images { get; set; }
}
Connection string as below
<connectionStrings>
<add name="ImageContext"
connectionString="server=.; database=Sample; integrated security =SSPI"
providerName="System.Data.SqlClient"/>
</connectionStrings>
ImageController as below
public class ImageController : Controller
{
private ImageContext db = new ImageContext();
// GET: /Image/
public ActionResult Index()
{
return View(db.Images.ToList());
}
// GET: /Image/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Image image = db.Images.Find(id);
if (image == null)
{
return HttpNotFound();
}
return View(image);
}
}
Have created views as below
public class ImageController : Controller
{
private ImageContext db = new ImageContext();
// GET: /Image/
public ActionResult Index()
{
return View(db.Images.ToList());
}
// GET: /Image/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Image image = db.Images.Find(id);
if (image == null)
{
return HttpNotFound();
}
return View(image);
}
// GET: /Image/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Image image = db.Images.Find(id);
if (image == null)
{
return HttpNotFound();
}
return View(image);
}
// POST: /Image/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Image image = db.Images.Find(id);
db.Images.Remove(image);
db.SaveChanges();
return RedirectToAction("Index");
}
}
}
My create.cshtml (view) as below
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ImageName)
</th>
<th>
#Html.DisplayNameFor(model => model.ImagePicInBytes)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ImageName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ImagePicInBytes)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
I have the below 3 questions
How can I create a new record in datatable by uploading new image from file system to Varbinary column in database?
How can I have the view to have FILEUPLOAD control in the 'create View' and 'Edit view'
Can I use HttpPostedFileBase to achieve the above from Create.cshtml? If yes: how? Any suggestions or reference links available?
first of all create a viewmodel for Image class
public class ImageViewModel
{
public string ImageName {get; set;}
public HttpPostedFileBase ImagePic {get; set;}
}
then for uploading a photo in your create view
#model ExmpleProject.Models.ImageViewModel
#using (Html.BeginForm("Create", "ControllerName", FormMethod.Post, new {enctype="multipart/form-data"})){
#Html.AntiForgeryToken()
#Html.LabelFor(m => m.ImageName)
#Html.TextBoxFor(m => m.ImageName)
#Html.LabelFor(m => m.ImagePic )
#Html.TextBoxFor(m => m.ImagePic , new { type = "file" })
<br />
<input type="submit" name="Submit" id="Submit" value="Upload" />
}
then in post method of your controller for create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ImageViewModel model)
{
if (ModelState.IsValid)
{
var uploadedFile = (model.ImagePic != null && model.ImagePic.ContentLength > 0) ? new byte[model.ImagePic.InputStream.Length] : null;
if (uploadedFile != null)
{
model.ImagePic.InputStream.Read(uploadedFile, 0, uploadedFile.Length);
}
Image image = new Image
{
ImageName = model.ImageName,
ImagePicInBytes = uploadedFile
}
db.Create(image);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
so for your edit method you can do similar implementation but instead of Create(image) use Update(image)

The 'number' property on 'Employee' could not be set to a 'System.Decimal' value

The 'number' property on 'Employee' could not be set to a 'System.Decimal' value. You must set this property to a non-null value of type 'System.Double'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The 'number' property
on 'Employee' could not be set to a 'System.Decimal' value. You must set this
property to a non-null value of type 'System.Double'.
Source Error:
Line 16: {
Line 17: EmployeeContext empcon = new EmployeeContext();
Line 18: Employee employ = empcon.employees.Single(emp => emp.empid ==
id);
Line 19: return View(employ);
Line 20: }
Please anyone help me
[Table("tbl_employee")]
public class Employee
{
[Key]public int empid { get; set; }
public string name { get; set; }
public string Address { get; set;}
public double number { get; set; }
}
public class EmployeeContext :DbContext
{
public DbSet<Employee> employees { get; set; }
}
View:
#model Employee_data.Models.Employee
#{
ViewBag.Title = "Emloyee Details";
}
<h2>Emloyee Details</h2>
<table style="font-family:Arial">
<tr>
<td>
<b>employee id</b>
</td>
<td>#Model.empid</td>
</tr>
<tr>
<td>
<b>employee Name</b>
</td>
<td>#Model.name</td>
</tr>
<tr>
<td>
<b>employee address</b>
</td>
<td>#Model.Address</td>
</tr>
<tr>
<td>
<b>employee number</b>
</td>
<td>#Model.number</td>
</tr>
</table>
#Html.ActionLink("click me", "Details", new { id = "1" })
Global.asax:
protected void Application_Start()
{
Database.SetInitializer<Employee_data.Models.EmployeeContext>(null);
}
Controller:
public ActionResult Details(int id)
{
EmployeeContext empcon = new EmployeeContext();
Employee employ = empcon.employees.Single(emp => emp.empid == id);
return View(employ);
}
web.config:
<connectionStrings>
<add name="EmployeeContext"
connectionString="Data Source=server;Initial Catalog=Testdb;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Route config:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "emp", action = "Details",
id = UrlParameter.Optional }
);
}
Set it to Decimal
[Key]
public int empid { get; set; }
public string name { get; set; }
public string Address { get; set;}
public Decimal number { get; set; }
I think it will work..
try this one..
This error is thrown if you attempt to call this controller action and
you do not specify the id either in the path portion or as query
string parameter. Since your controller action takes an id as
parameter you should make sure that you always specify this parameter.
Make sure that when you are requesting this action you have specified
a valid id in the url:
Check this link
If empid is your key try this
[Key] public int empid{ get; set; }

Resources