Validation Error without posting data in MVC - asp.net-mvc

I am using same form for Inserting new records and updating existing records. But, issue is that validation on all controls are shown as soon as form is loaded i.e. it should display validation message summary once this does not match criteria. I want to avoid validation message summary before clicking on submit button.
Controller:
using CRUD_logudTycoon_Revision_3.Context;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace CRUD_logudTycoon_Revision_3.Controllers
{
public class HomeController : Controller
{
// GET: Home
testEntities dbContext = new testEntities();
public ActionResult HomePage()
{
return View();
}
public ActionResult Student(tbl_Student obj)
{
if (obj != null)
{
return View(obj);
}
return View("Student");
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult AddStudent(tbl_Student stu)
{
if (ModelState.IsValid)
{
tbl_Student res = new tbl_Student();
res.ID = stu.ID;
res.Name = stu.Name;
res.Fname = stu.Fname;
res.Email = stu.Email;
res.Mobile = stu.Mobile;
res.Description = stu.Description;
if (stu.ID == 0)
{
dbContext.tbl_Student.Add(res);
dbContext.SaveChanges();
}
else
{
dbContext.Entry(res).State = System.Data.Entity.EntityState.Modified;
dbContext.SaveChanges();
}
}
ModelState.Clear();
//return View("Student");
return RedirectToAction("StudentList");
}
public ActionResult StudentList()
{
var result = dbContext.tbl_Student.ToList();
return View(result);
}
public ActionResult Delete(int ID)
{
var result = dbContext.tbl_Student.Where(x => x.ID == ID).First();
dbContext.tbl_Student.Remove(result);
dbContext.SaveChanges();
var newlist = dbContext.tbl_Student.ToList();
return View("StudentList", newlist);
}
}
}
Student Action (Insert/Edit):
#model CRUD_logudTycoon_Revision_3.Context.tbl_Student
#{
ViewBag.Title = "Student";
}
<style>
.error {
color: red;
}
</style>
<h2>Student Registration Page</h2>
#using (Html.BeginForm("AddStudent", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="container">
<div class="form-group">
#Html.HiddenFor(x => x.ID)
#Html.Label("Student Name")
#Html.ValidationMessageFor(x => x.Name, "", new { #class = "error" })
#Html.TextBoxFor(x => x.Name, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.Label("Father Name")
#Html.ValidationMessageFor(x => x.Fname, "", new { #class = "error" })
#Html.TextBoxFor(x => x.Fname, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.Label("Email")
#Html.ValidationMessageFor(x => x.Email, "", new { #class = "error" })
#Html.TextBoxFor(x => x.Email, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.Label("Mobile")
#Html.ValidationMessageFor(x => x.Mobile, "", new { #class = "error" })
#Html.TextBoxFor(x => x.Mobile, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.Label("Description")
#Html.ValidationMessageFor(x => x.Description, "", new { #class = "error" })
#Html.TextBoxFor(x => x.Description, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.TextBox("btn_Submit", "Submit", new { type = "Submit" })
#Html.TextBox("btn_Reset", "Reset", new { type = "Reset" })
</div>
</div>
}
DB Scripts:
CREATE TABLE [dbo].[tbl_Student]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](150) NULL,
[Fname] [varchar](150) NULL,
[Email] [varchar](150) NULL,
[Mobile] [varchar](150) NULL,
[Description] [varchar](350) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CRUD_logudTycoon_Revision_3.Context
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class tbl_Student
{
public int ID { get; set; }
[Required(ErrorMessage ="Name is requried")]
public string Name { get; set; }
[Required(ErrorMessage = "Father Name is requried")]
public string Fname { get; set; }
[Required(ErrorMessage = "Email is requried")]
[EmailAddress]
public string Email { get; set; }
[Required(ErrorMessage = "Mobile is requried")]
[MinLength(10,ErrorMessage ="10 Digit Mobile No. is required")]
[MaxLength(10, ErrorMessage = "10 Digit Mobile No. is required")]
public string Mobile { get; set; }
[Required(ErrorMessage = "Description is requried")]
public string Description { get; set; }
}
}

Related

How to store and display SelectList data

I am using SelectList to populate dropdownlists in my view. It works for the Create and Edit views to store ID value data in a table. How do I retrieve the 'Name' value to display in a Details view?
Model
Public Class Employee {
[Key]
public int ID { get; set;}
public string UserName {get; set; }
public byte Gender { get; set; }
}
ViewModel
public class EmployeeEditViewModel {
public int ID { get; set; }
public string UserName { get; set; }
public SelectList GenderList { get; set; }
public EmployeeEditViewModel () {
GenderList = CommonHelper.GenderList(null);
}
}
Helper
public static SelectList GenderList(object selected)
{
return new SelectList(new[]
{
new { Value = 0, Name = "Male" },
new { Value = 1, Name = "Female" }
}
, "Value", "Name", selected);
}
Edit View
#model Models.ViewModel.EmployeeEditViewModel
#using (Html.BeginForm()) {
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.UserName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.UserName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GenderList, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Gender, Model.GenderList, "- Select -", new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GenderList, "", new { #class = "text-danger" })
</div>
</div>
}
Controller
[HttpPost]
public ActionResult CreateEmployee(EmployeeEditViewModel emProfile)
{
try
{
if (ModelState.IsValid)
{
Employee newUser = new Employee();
newUser.UserName = emProfile.UserName;
newUser.Gender = emProfile.Gender;
userRepository.Add(newUser);
userRepository.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception ex)
{ }
return View(emProfile);
}
So far it works great, I am able to create, edit Employee records and 1 or 0 is stored in the table for the gender.
But when I want to display the employee data in a details view how do I get the text 'Male' or 'Female'?
I ended up creating a helper method to retrieve the text.
public static string GetTextFromSelectList(int id, string listName)
{
string selectedText = string.Empty;
SelectListItem selectedItem;
switch (listName)
{
case "Gender":
selectedItem = Helper.CommonHelper.GenderList(null).FirstOrDefault(x => x.Value == id.ToString());
selectedText = selectedItem == null ? null : selectedItem.Text;
break;
default:
selectedText = null;
break;
}
return selectedText;
}

MVC MultipleModel DropdownlistFor SaveChanges()

HI i Have a MultipleModel View with CompanyName and EmployeeRange. CompanyName contains names of companies with a Relationship link to EmployeeRange (int) Field.
The Employee Range is basically
0-9
10-19
20-49
I can create and SaveChanges for a new Company Name Field.
Please help With Saving Selected value from the EmployeeRange DropDownListFor to DB.
Here is the Code
//MultipleModel.cs
public partial class MultipleModel
{
public MultipleModel()
{
CompanyEntities = new company();
EmployeeEntities = new Employee();
}
public company CompanyEntities { get; set; }
public Employee EmployeeEntities { get; set; }
}
//CompanyController.cs
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RegisterCompany(MultipleModel model)
{
if (ModelState.IsValid)
{
//GET VARIBALE FROM DB
var addComanyName = db.companies.Add(model.CompanyEntities);
//GET VARIABLLE
addComanyName.COMPANY_NAME = model.CompanyEntities.COMPANY_NAME;
//ADD VARIBALE TO DB
db.companies.Add(addComanyName);
db.SaveChanges();
return RedirectToAction("index");
}
return View();
}
//RegisterCompany.cshtml
#model EISystem.Models.MultipleModel
#Html.DropDownListFor(m => m.CompanyEntities, new SelectList(ViewBag.products, "Employees_Range_ID", "Employees_Range"), "Select Number of Employees")
?? How Do i view the DropDownListFor so that selected Value can be POST to Controller and later be saved to DB?
You should use another class which is ViewModel for your MultipleModel class.
Like:
public class MultipleModelViewModel
{
public int SelectedProductId { get; set; }
public List<Products> ProductList{ get; set; }
public string Name { get; set; }
}
In a View
#model MultipleModelViewModel
#using (Html.BeginForm("RegisterCompany", "Company", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.SelectedProductId , htmlAttributes: new { #class = "form-control" })
#Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.ProductList, "Id", "Name"), "Select Product", new { #class = "form-control " })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "form-control " })
#Html.TextBoxFor(model => model.Name, new { #class = "form-control" })
</div>
<button type="Submit" class="btn btn-success " id="Save-btn">
Save
</button>
}
Controller:
//Get
public ActionResult RegisterCompany()
{
var model = new MultipleModelViewModel (){
Name = model.Name,
Products = db.Products.Select(x=>new {Id=x.Id, Name=x.Name).ToList()
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RegisterCompany(MultipleModelViewModel model)
{
if (ModelState.IsValid)
{
var company = new Company(){
Name = model.Name,
Product = db.Products.Find(model.SelectedProductId)
};
db.companies.Add(company);
db.SaveChanges();
return RedirectToAction("index");
}
return View();
}

MVC 4 - Compiler Error Message: CS1061

I have created an image gallery upload which works fine with just the Image Description and Upload image. now i am adding a drop down to categories the images into a specific group folder.
My Database table is as follows:
CREATE TABLE [WebsitePhotosGallery] (
[PhotoId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[Decription] NVARCHAR (150) NOT NULL,
[ImagePath] NVARCHAR (200) NOT NULL,
[ThumbPath] NVARCHAR (200) NOT NULL,
[CreatedOn] DATETIME NOT NULL,
[GalleryCategory] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([PhotoId] ASC)
);
Note: I added [GalleryCategory] NVARCHAR (50) NOT NULL now because of the drop down needed.
My Database Model Looks like this:
namespace T.Database
{
using System;
using System.Collections.Generic;
public partial class WebsitePhotosGallery
{
public System.Guid PhotoId { get; set; }
public string Decription { get; set; }
public string ImagePath { get; set; }
public string ThumbPath { get; set; }
public System.DateTime CreatedOn { get; set; }
public string GalleryCategory { get; set; }
}
}
I also have this model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace T.WebsitePhotosGallery
{
public class Photo
{
[Key]
public int PhotoId { get; set; }
[Display(Name = "Decription")]
[Required]
public String Decription { get; set; }
[Display(Name = "Image Path")]
public String ImagePath { get; set; }
[Display(Name = "Thumb Path")]
public String ThumbPath { get; set; }
[Display(Name = "Created On")]
public DateTime CreatedOn { get; set; }
[Display(Name = "Gallery Category")]
[Required]
public String GalleryCategory { get; set; }
}
}
My Controller looks like this:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using T.Database;
using T.Models.WebsitePhotosGallery;
namespace T.Controllers
{
public class GalleryController : Controller
{
//
// GET: /PhotosGallery/
DatabaseEntity db = new DatabaseEntity();
public ActionResult Index(string filter = null, int page = 1, int pageSize = 18)
{
var records = new PagedList<WebsitePhotosGallery>();
ViewBag.filter = filter;
records.Content = db.WebsitePhotosGalleries.Where(x => filter == null || (x.Decription.Contains(filter)))
.OrderByDescending(x => x.Decription)
.Skip((page - 1)*pageSize)
.Take(pageSize)
.ToList();
//Count
records.TotalRecords = db.WebsitePhotosGalleries.Where(x => filter == null || (x.Decription.Contains(filter))).Count();
records.CurrentPage = page;
records.PageSize = pageSize;
return View(records);
}
[HttpGet]
public ActionResult Create()
{
var photo = new Photo();
return View(photo);
}
public Size NewImageSize(Size imageSize, Size newSize)
{
Size finalSize;
double tempval;
if (imageSize.Height > newSize.Height || imageSize.Width > newSize.Width)
{
if (imageSize.Height > imageSize.Width)
tempval = newSize.Height / (imageSize.Height * 1.0);
else
tempval = newSize.Width / (imageSize.Width * 1.0);
finalSize = new Size((int)(tempval * imageSize.Width), (int)(tempval * imageSize.Height));
}
else
finalSize = imageSize; //image is already small size
return finalSize;
}
private void SaveToFolder(Image img, string fileName, string extension, Size newSize, string pathToSave)
{
//Get new resolution
Size imgSize = NewImageSize(img.Size, newSize);
using (System.Drawing.Image newImg = new Bitmap(img, imgSize.Width, imgSize.Height))
{
newImg.Save(Server.MapPath(pathToSave), img.RawFormat);
}
}
[HttpPost]
public ActionResult Create(WebsitePhotosGallery photo, IEnumerable<HttpPostedFileBase> files)
{
if (!ModelState.IsValid)
return View(photo);
if (files.Count() == 0 || files.FirstOrDefault() == null)
{
ViewBag.error = "Please choose a file";
return View(photo);
}
var model = new WebsitePhotosGallery();
foreach (var file in files)
{
if (file.ContentLength == 0) continue;
model.Decription = photo.Decription;
var fileName = Guid.NewGuid().ToString();
var s = System.IO.Path.GetExtension(file.FileName);
if (s != null)
{
var extension = s.ToLower();
using (var img = System.Drawing.Image.FromStream(file.InputStream))
{
model.ThumbPath = String.Format("/GalleryImages/Thumbs/{0}{1}", fileName, extension);
model.ImagePath = String.Format("/GalleryImages/{0}{1}", fileName, extension);
//Save thumbnail size image, 240 x 159
SaveToFolder(img, fileName, extension, new Size(240, 159), model.ThumbPath);
//Save large size image, 1024 x 683
SaveToFolder(img, fileName, extension, new Size(1024, 683), model.ImagePath);
}
}
//Save record to database
model.CreatedOn = DateTime.Now;
model.PhotoId= Guid.NewGuid();
model.GalleryCategory = photo.GalleryCategory;
db.WebsitePhotosGalleries.Add(model);
db.SaveChanges();
}
return View();
}
}
}
And finally my View looks like this which is where the error now comes is, I hard coded the drop down list:
#using T.Database
#model T.WebsitePhotosGallery.Photo
#{
var galleryCategories = new List<SelectListItem>
{
new SelectListItem {Text = "Group 1", Value = "Group 1"},
new SelectListItem {Text = "Group 2", Value = "Group 2"}
};
}
<h2>Create</h2>
<h2>Upload Images</h2>
<div class="well">
#using (Html.BeginForm("Create", "Gallery", FormMethod.Post, new { id = "photogallery", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(m => Model.Decription, new { #class = "control-label col-sm-3", required = ""})
<div class="col-sm-5">
#Html.TextBoxFor(m => m.Decription, new { #class = "form-control required" })
#Html.ValidationMessageFor(model => model.Decription)
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => Model.GalleryCategory, new { #class = "control-label col-sm-3", required = "" })
<div class="col-sm-5">
#Html.DropDownListFor(m => m.Product, productCategory, "-- Select Product --", new {#class = "form-control", required = ""})
#Html.ValidationMessageFor(model => model.GalleryCategory)
</div>
</div>
<div class="form-group">
#Html.Label("Choose Image(s)", new { #class = "control-label col-sm-3", required = "" })
<div class="col-sm-5">
<input type="file" name="files" multiple="multiple" accept=".jpg, .png, .gif" required />
</div>
</div>
<div class="form-group">
<div class="col-sm-5 col-sm-offset-3">
<input type="submit" value="Save" class="btn btn-primary" />
<div style="color:red">
#ViewBag.error
</div>
</div>
</div>
</div>
}
</div>
So now immediately when i want to view the Create page i am now getting this error:
Server Error in '/' Application.
Compilation Error
Description: An error occurred during the compilation of a resource
required to service this request. Please review the following specific
error details and modify your source code appropriately.
Compiler Error Message: CS1061: 'T.Models.WebsitePhotosGallery.Photo'
does not contain a definition for 'GalleryCategory' and no extension
method 'GalleryCategory' accepting a first argument of type
'T.Models.WebsitePhotosGallery.Photo' could be found (are you missing
a using directive or an assembly reference?)
Source Error:
Line 30: Line 31:
Line 32: #Html.LabelFor(m => Model.GalleryCategory,
new { #class = "control-label col-sm-3", required = "" }) Line 33:
Line 34: #Html.TextBoxFor(m
=> m.GalleryCategory, new { #class = "form-control required" })
Source File: c:\Users\Huha\Source\Workspaces\Panel\panel\Gallery
Panel\Views\Gallery\Create.cshtml Line: 32
Your help is much appreciated, thank you.
Did you split the solution into multiple projects? If so, try force building the project that contains the class Photo. It sounds like the WebApplication only sees an outdated DLL, in which the Photo.GalleryCategory property is not yet present.
If build fails (or is skipped) for the Photo project, then the last-built version of the DLL will be used.
From here, it looks like your view and htmlhelper are a little off. You should be referencing the property via lambda and not via the Model. Basically, you're view goes from:
<div class="form-group">
#Html.LabelFor(m => Model.GalleryCategory, new { #class = "control-label col-sm-3", required = "" })
<div class="col-sm-5">
#Html.TextBoxFor(m => m.GalleryCategory, new { #class = "form-control required" })
#Html.ValidationMessageFor(model => model.GalleryCategory)
</div>
</div>
To the following (note change to #Html.LabelFor(...) call):
<div class="form-group">
#* Reference m. not Model. *#
#Html.LabelFor(m => m.GalleryCategory, new { #class = "control-label col-sm-3", required = "" })
<div class="col-sm-5">
#Html.TextBoxFor(m => m.GalleryCategory, new { #class = "form-control required" })
#Html.ValidationMessageFor(model => model.GalleryCategory)
</div>
</div>

ViewModel Contents are Null after Posting Form to Controller

So the ViewModel has 2 sets of data.
The CurrentDetails and UpdatedDetails. Both are instances of the same class which carries strings and whatnot inside etc.
This method has worked with all other views and models I've attempted with, but for THIS one instance, when the form is posted to the controller, its contents (CurrentDetails and UpdatedDetails) are both found to be null.
I've tried changing the parameter name from model to test and to other arbitrary things, but to no avail.
The one thing that worked (but is not a solution to me) is NOT having instances of the class inside the ViewModel, and just having the data there (but I don't see why I should be forced to do things this way.
Here's the controller:
[HttpPost]
public ActionResult FloristProfile(MerchantFloristProfileViewModel test)
{
if (!ModelState.IsValid)
return View(test);
using (var db = new ApplicationDbContext())
{
Florist florist = db.Florists.Find(MerchantBase.FloristID);
if (Request.Form["editSubmit"] != null)
{
florist.Name = test.UpdatedDetails.Name;
florist.Website = test.UpdatedDetails.Website;
db.SaveChanges();
return RedirectToAction("FloristProfile");
}
else if (Request.Form["photoSubmit"] != null)
{
if (test.CurrentDetails.File.ContentLength > 0)
{
CloudBlobContainer container = FlowerStorage.GetCloudBlobContainer();
string blobName = String.Format("florist_{0}.jpg", Guid.NewGuid().ToString());
CloudBlockBlob photoBlob = container.GetBlockBlobReference(blobName);
photoBlob.UploadFromStream(test.CurrentDetails.File.InputStream);
florist.LogoPath = blobName;
florist.isRendering = true;
db.SaveChanges();
return RedirectToAction("FloristProfile");
}
}
}
return Content("Invalid Request");
}
View:
#using (Html.BeginForm("FloristProfile", "Merchant", FormMethod.Post, new { #class = "form-horizontal" }))
{
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
#Html.HiddenFor(x => x.CurrentDetails.FloristID)
#Html.HiddenFor(x => x.CurrentDetails.Name)
#Html.HiddenFor(x => x.CurrentDetails.StaffCount)
#Html.HiddenFor(x => x.CurrentDetails.StoreCount)
#Html.HiddenFor(x => x.CurrentDetails.Website)
<div class="form-group">
#Html.LabelFor(x => x.UpdatedDetails.Name, new { #class = "col-sm-2 control-label" })
<div class="col-sm-10">
#Html.TextBoxFor(x => x.UpdatedDetails.Name, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(x => x.UpdatedDetails.Website, new { #class = "col-sm-2 control-label" })
<div class="col-sm-10">
#Html.TextBoxFor(x => x.UpdatedDetails.Website, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="editSubmit" class="btn btn-success">Save</button>
</div>
</div>
}
ViewModel:
public class MerchantFloristProfileViewModel
{
public class FloristProfileDetails
{
public int FloristID { get; set; }
[Required(ErrorMessage = "Please Enter a Name")]
public string Name { get; set; }
[DataType(DataType.Url)]
[Required(ErrorMessage = "Please Enter a Website")]
public string Website { get; set; }
public int StoreCount { get; set; }
public int StaffCount { get; set; }
// For Picture Upload
public HttpPostedFileBase File { get; set; }
}
public FloristProfileDetails CurrentDetails;
public FloristProfileDetails UpdatedDetails;
}
Both CurrentDetails and UpdatedDetails in your MerchantFloristProfileViewModel model are fields, not properties (no getter/setter) so the DefaultModelBinder cannnot set the values. Change them to
public FloristProfileDetails CurrentDetails { get; set; }
public FloristProfileDetails UpdatedDetails { get; set; }
But you should not be sending all that extra data to the view, then sending it all back again unchanged. Apart from the extra overhead, any malicious user could alter the values in the hidden fields causing your app to fail. Just get the original from the repository again if you need it in the POST method

Get two tables data on a single MVC View

I am not so much experienced with MVC in ASP.NET. Currently working on Visual Studio 2015 Community on a demo MVC project.
I am having difficulties having two tables combined in a view.
Following are two tables of concern from few tables.
I want to show data from both the tables at the same time in a single View(HTML Page).
TABLE - COMPLAIN
CREATE TABLE [dbo].[COMPLAIN](
[JOBSHEET_NO] [int] IDENTITY(1,1) NOT NULL,
[COMPANY_NAME] [nvarchar](50) NULL,
[MODEL_NAME] [nvarchar](50) NULL,
[IMEI_SRNO] [nvarchar](50) NULL,
[BATTERY_WITH_MOBILE] [nvarchar](50) NULL,
[MEMORYCARD_WITH_MOBILE] [nvarchar](50) NULL,
[FAULT_ID] [int] NOT NULL,
[CUSTOMER_NAME] [nvarchar](50) NULL,
[CUSTOMER_MOBILE] [nvarchar](50) NULL,
[ASSIGNED_TO_TECHNICIAN] [nvarchar](50) NULL,
[REMARKS] [nvarchar](500) NULL,
[CREATE_TIMESTAMP] [datetime] NULL,
[LAST_EDIT_TIMESTAMP] [datetime] NULL,
[IN_TIMESTAMP] [datetime] NULL,
[USER_ID] [nvarchar](50) NULL,
[ESTIMATE_AMOUNT] [float] NULL,
[ESTIMATE_AMOUNT_OK_FROM_CUSTOMER] [nvarchar](50) NULL,
[OUT_TIMESTAMP] [datetime] NULL,
[JOBSHEET_COMPLETE_STATUS] [nvarchar](50) NULL,
[NARRATION] [nvarchar](500) NULL,
CONSTRAINT [PK_COMPLAIN] PRIMARY KEY CLUSTERED
(
[JOBSHEET_NO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
TABLE - REPAIRING
CREATE TABLE [dbo].[REPAIRING](
[JOBSHEET_NO] [int] NOT NULL,
[IN_TIMESTAMP] [datetime] NULL,
[CREATE_TIMESTAMP] [datetime] NULL,
[LAST_EDIT_TIMESTAMP] [datetime] NULL,
[ESTIMATE_AMOUNT] [float] NULL,
[ESTIMATE_AMOUNT_OK_FROM_CUSTOMER] [nvarchar](50) NULL,
[START_REPAIRING_TIMESTAMP] [datetime] NULL,
[END_REPAIRING_TIMESTAMP] [datetime] NULL,
[OUT_TIMESTAMP] [datetime] NULL,
[USER_ID] [nvarchar](50) NULL,
[NARRATION] [nvarchar](500) NULL,
CONSTRAINT [PK_REPAIRING] PRIMARY KEY CLUSTERED
(
[JOBSHEET_NO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[REPAIRING] WITH CHECK ADD CONSTRAINT [FK_REPAIRING_COMPLAIN] FOREIGN KEY([JOBSHEET_NO])
REFERENCES [dbo].[COMPLAIN] ([JOBSHEET_NO])
GO
ALTER TABLE [dbo].[REPAIRING] CHECK CONSTRAINT [FK_REPAIRING_COMPLAIN]
GO
I am having FK relationship between those two tables.
I would also like to know if data from both the tables can be available without any FK relationship.
Following are my models.
COMPLAIN.cs
namespace WebMSM.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public partial class COMPLAIN
{
[Key]
[ReadOnly(true)]
[Required]
[DisplayName("JOBSHEET NO")]
public int JOBSHEET_NO { get; set; }
[Required]
[DisplayName("COMPANY NAME")]
public string COMPANY_NAME { get; set; }
[Required]
[DisplayName("MODEL NAME")]
public string MODEL_NAME { get; set; }
[Required]
[DisplayName("IMEI")]
public string IMEI_SRNO { get; set; }
[Required]
[DisplayName("BATTERY WITH MOBILE")]
public string BATTERY_WITH_MOBILE { get; set; }
[Required]
[DisplayName("MEMORY CARD WITH MOBILE")]
public string MEMORYCARD_WITH_MOBILE { get; set; }
[Required]
[DisplayName("FAULT")]
public int FAULT_ID { get; set; }
[Required]
[DisplayName("CUSTOMER NAME")]
public string CUSTOMER_NAME { get; set; }
[Required]
[DisplayName("CUSTOMER MOBILE")]
public string CUSTOMER_MOBILE { get; set; }
[Required]
[DisplayName("TECHNICIAN")]
public string ASSIGNED_TO_TECHNICIAN { get; set; }
[DisplayName("REMARKS")]
public string REMARKS { get; set; }
public Nullable<System.DateTime> CREATE_TIMESTAMP { get; set; }
public Nullable<System.DateTime> LAST_EDIT_TIMESTAMP { get; set; }
public Nullable<System.DateTime> IN_TIMESTAMP { get; set; }
[Required]
[DisplayName("USER ID")]
public string USER_ID { get; set; }
[DisplayName("ESTIMATE AMOUNT")]
public Nullable<double> ESTIMATE_AMOUNT { get; set; }
[DisplayName("ESTIMATE AMOUNT OK?")]
public string ESTIMATE_AMOUNT_OK_FROM_CUSTOMER { get; set; }
public Nullable<System.DateTime> OUT_TIMESTAMP { get; set; }
[DisplayName("STATUS")]
public string JOBSHEET_COMPLETE_STATUS { get; set; }
[Required]
[DisplayName("NARRATION")]
public string NARRATION { get; set; }
public virtual MASTER_FAULT MASTER_FAULT { get; set; }
public virtual REPAIRING REPAIRING { get; set; }
}
}
REPAIRING.cs
namespace WebMSM.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public partial class REPAIRING
{
[Required]
[DisplayName("JOBSHEET NO")]
public int JOBSHEET_NO { get; set; }
public Nullable<System.DateTime> IN_TIMESTAMP { get; set; }
public Nullable<System.DateTime> CREATE_TIMESTAMP { get; set; }
public Nullable<System.DateTime> LAST_EDIT_TIMESTAMP { get; set; }
[Required]
[DisplayName("ESTIMATE AMOUNT")]
public Nullable<double> ESTIMATE_AMOUNT { get; set; }
[Required]
[DisplayName("ESTIMATE AMOUNT OK?")]
public string ESTIMATE_AMOUNT_OK_FROM_CUSTOMER { get; set; }
[DisplayName("START REPAIR TIME")]
public Nullable<System.DateTime> START_REPAIRING_TIMESTAMP { get; set; }
[DisplayName("END REPAIR TIME")]
public Nullable<System.DateTime> END_REPAIRING_TIMESTAMP { get; set; }
[DisplayName("OUT TIME")]
public Nullable<System.DateTime> OUT_TIMESTAMP { get; set; }
public string USER_ID { get; set; }
[DisplayName("NARRATION")]
public string NARRATION { get; set; }
public virtual COMPLAIN COMPLAIN { get; set; }
}
}
Now I have created a RepairingController which displays list of COMPLAINs on its index View.
From that View, by Clicking 'Edit' link, I would like to go to Edit view in which data from both the tables about that record should be available.
Following is RepairingController.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebMSM.Models;
namespace WebMSM.Controllers
{
public class RepairingController : Controller
{
private MSMContext db = new MSMContext();
// GET: Repairing
public ActionResult Index()
{
return View(db.COMPLAINs.ToList());
}
// GET: Repairing/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
REPAIRING rEPAIRING = db.REPAIRINGs.Find(id);
if (rEPAIRING == null)
{
return HttpNotFound();
}
return View(rEPAIRING);
}
// GET: Repairing/Create
public ActionResult Create()
{
return View();
}
// POST: Repairing/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "JOBSHEET_NO,IN_TIMESTAMP,CREATE_TIMESTAMP,LAST_EDIT_TIMESTAMP,ESTIMATE_AMOUNT,ESTIMATE_AMOUNT_OK_FROM_CUSTOMER,START_REPAIRING_TIMESTAMP,END_REPAIRING_TIMESTAMP,OUT_TIMESTAMP,USER_ID,NARRATION")] REPAIRING rEPAIRING)
{
if (ModelState.IsValid)
{
db.REPAIRINGs.Add(rEPAIRING);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(rEPAIRING);
}
// GET: Repairing/Edit/5
public ActionResult Edit(int? id)
{
var lstOKNOTOK = new List<SelectListItem>()
{
new SelectListItem {Text="OK",Value="OK" },
new SelectListItem {Text="NOT_OK",Value="NOT_OK" },
};
ViewBag.ESTIMATE_AMOUNT_OK_FROM_CUSTOMER = lstOKNOTOK;
REPAIRING rEPAIRING = db.REPAIRINGs.Find(id);
if (rEPAIRING == null)
{
return HttpNotFound();
}
return View(rEPAIRING);
}
// POST: Repairing/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "JOBSHEET_NO,IN_TIMESTAMP,CREATE_TIMESTAMP,LAST_EDIT_TIMESTAMP,ESTIMATE_AMOUNT,ESTIMATE_AMOUNT_OK_FROM_CUSTOMER,START_REPAIRING_TIMESTAMP,END_REPAIRING_TIMESTAMP,OUT_TIMESTAMP,USER_ID,NARRATION")] REPAIRING rEPAIRING)
{
if (ModelState.IsValid)
{
db.Entry(rEPAIRING).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(rEPAIRING);
}
// GET: Repairing/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
REPAIRING rEPAIRING = db.REPAIRINGs.Find(id);
if (rEPAIRING == null)
{
return HttpNotFound();
}
return View(rEPAIRING);
}
// POST: Repairing/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
REPAIRING rEPAIRING = db.REPAIRINGs.Find(id);
db.REPAIRINGs.Remove(rEPAIRING);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Following is Edit.cshtml View For RepairingController.cs
#model WebMSM.Models.REPAIRING
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>REPAIRING</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.JOBSHEET_NO)
<div class="form-group">
#Html.LabelFor(model => model.JOBSHEET_NO, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.TextBoxFor(model => model.JOBSHEET_NO, new { #class = "form-control" ,#readonly="readonly"} )
#Html.ValidationMessageFor(model => model.JOBSHEET_NO, "", new { #class = "text-danger" })
</div>
</div>
#*<div class="form-group">
#Html.LabelFor(model => model.IN_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.IN_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.IN_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CREATE_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.CREATE_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CREATE_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LAST_EDIT_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.LAST_EDIT_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LAST_EDIT_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>*#
<div class="form-group">
#Html.LabelFor(model => model.ESTIMATE_AMOUNT, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.ESTIMATE_AMOUNT, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ESTIMATE_AMOUNT, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ESTIMATE_AMOUNT_OK_FROM_CUSTOMER, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.DropDownListFor(model => model.ESTIMATE_AMOUNT_OK_FROM_CUSTOMER,ViewBag.ESTIMATE_AMOUNT_OK_FROM_CUSTOMER as SelectList, new { #class = "form-control" } )
#Html.ValidationMessageFor(model => model.ESTIMATE_AMOUNT_OK_FROM_CUSTOMER, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.START_REPAIRING_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.START_REPAIRING_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.START_REPAIRING_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.END_REPAIRING_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.END_REPAIRING_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.END_REPAIRING_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OUT_TIMESTAMP, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.OUT_TIMESTAMP, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OUT_TIMESTAMP, "", new { #class = "text-danger" })
</div>
</div>
#*<div class="form-group">
#Html.LabelFor(model => model.USER_ID, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.USER_ID, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.USER_ID, "", new { #class = "text-danger" })
</div>
</div>*#
<div class="form-group">
#Html.LabelFor(model => model.NARRATION, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-6">
#Html.EditorFor(model => model.NARRATION, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.NARRATION, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-5 col-md-6">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Thanks in advance.
You should create a new view model class which has properties to represent data from both the tables
public class ComplaintDetailsVm
{
public Int JobSheetNo {set;get;}
public string CompanyName {set;get;}
public string CustomerName {set;get;}
public Decimal EsitmatedAmount {set;get;}
//Add other properties AS NEEDED
}
And use that for your view.
public ActionResult Edit(int id)
{
var vm = new ComplaintDetailsVm();
var r =db.REPAIRINGs.Find(id);
if(r!=null)
{
vm.JobSheetNo = r.JOBSHEET_NO;
vm.CustomerName= r.CUSTOMER_NAME;
//Map other properties here as needed
if(r.REPAIRING !=null)
{
vm.EstimatedAmount = r.ESTIMATED_AMOUNT;
//Map other properties here as needed
}
}
return View(vm);
}
And your view
#model ComplantDetailsVm
#using(Html.BeginForm())
{
#Html.TextBoxFor(s=>s.CompanyName)
#Html.TextBoxFor(s=>s.EstimatedAmount)
#Html.HiddenFor(s=>s.JobSheetNo)
<input type="submit" />
}
So when user posts the form, we need to read the data from our viewmodel object and use that for saving
[HttpPost]
public ActionResult Edit(ComplantDetailVm model)
{
if(ModelState.IsValid)
{
var e=db.COMPLAINs.FirstOrDefault(s=>s.JOBSHEET_NO==model.JobSheetNo);
if(e!=null)
{
// Update the property values
e.CompanyName = model.CompanyName;
//Map other properties also
db.Entry(e).State = EntityState.Modified;
db.SaveChanges();
//to do : Redirect to Success message page.
}
}
return View(model);
}

Resources