ASP.NET MVC - Object reference not set to an instance of an object in DropDownList - asp.net-mvc-4

I have a model Class
public partial class FEES
{
public FEES()
{
}
public long FEE_ID { get; set; }
public decimal AMOUNT { get; set; }
public int CURRENCY_ID { get; set; }
public string NAME { get; set; }
public virtual CURRENCIES CURRENCIES { get; set; }
}
ViewModel
public class FeesViewModel
{
public SelectList CurrenciesList { get; set; }
public FeesViewModelInput input { get; set; }
public class FeesViewModelInput
{
[HiddenInput]
public long FEE_ID { get; set; }
[Display(Name = "Amount")]
[Required(ErrorMessage = "Fee Amount Is Required!")]
[RegularExpression(#"^[0-9,.]+$", ErrorMessage = "Please enter proper currency format e.g. 2,500")]
public decimal AMOUNT { get; set; }
[Display(Name = "Currency")]
[Required(ErrorMessage = "Currency Is Required!")]
public int CURRENCY_ID { get; set; }
[Required(ErrorMessage = "Fee Name Is Required!")]
[Display(Name = "Fee Name")]
public string NAME { get; set; }
}
}
Small service for the ViewModel
public void createFees(FEES fee, FeesViewModel viewModel)
{
fee.FEE_ID = viewModel.input.FEE_ID;
fee.CURRENCY_ID = viewModel.input.CURRENCY_ID;
fee.NAME = viewModel.input.NAME.Trim();
}
I call the service and the ViewModel in my controller.
Controller
public ActionResult Create()
{
FeesViewModel fees = new FeesViewModel();
fees.CurrenciesList = new SelectList(_currenciesService.GetCurrencies().Where(c => c.ACTION_STATUS != 2), "CURRENCY_ID", "CURRENCY_NAME");
fees.FeeTypesList = new SelectList(_feetypesService.GetFeeTypes().Where(c => c.ACTION_STATUS != 2), "FEE_TYPE_ID", "FEE_TYPE_NAME");
return View();
}
[HttpPost]
public ActionResult Create(FeesViewModel fees)
{
try
{
if (ModelState.IsValid)
{
//check if values is duplicate
if (_feesService.GetFees().Where(c => c.ACTION_STATUS != 2).Any(c => c.NAME.ToLower().Trim() == fees.input.NAME.ToLower().Trim()))
{
this.AddNotification("Fee Name already exist.<br/> Kindly verify the data.", NotificationType.ERROR);
}
else
{
var fee = new BPP.CCSP.Admin.Web.BPPCCSPAdminFeesService.FEES();
var helper = new FeesService();
helper.createFees(fee, fees);
_feesService.AddFee(fee);
var notif = new UINotificationViewModel()
{
notif_message = "Record saved successfully",
notif_type = NotificationType.SUCCESS,
};
TempData["notif"] = notif;
return RedirectToAction("Index");
}
}
}
catch (Exception e)
{
this.AddNotification("Fees cannot be added.<br/> Kindly verify the data.", NotificationType.ERROR);
}
fees.CurrenciesList = new SelectList(_currenciesService.GetCurrencies().Where(c => c.ACTION_STATUS != 2), "CURRENCY_ID", "CURRENCY_NAME");
return View(fees);
}
And the View
#model BPP.CCSP.Admin.Web.ViewModels.FeesViewModel
#{
//ViewBag.Title = "Create";
}
<div class=" box box-body box-primary">
#using (Html.BeginForm("Create", "Fees", FormMethod.Post, new { #class = "form-horizontal", #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, null, new { #class = "text-danger" })
#*#Html.HiddenFor(model => model.faculty_activation_date, new { #Value = System.DateTime.Now })*#
<div class="row .col">
<div style="margin-top:20px" class="mainbox col-md-12 col-md-offset-0 col-sm-8 col-sm-offset-2">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Create Fee</div>
</div>
<div class="panel-body">
<div class="col-md-6">
<div>
#Html.LabelFor(model => model.input.NAME, "Fee Name")
#Html.TextBoxFor(model => model.input.NAME, new { #style = "border-radius:3px;", #type = "text", #class = "form-control", #placeholder = Html.DisplayNameFor(m => m.input.NAME), #autocomplete = "on" })
#Html.ValidationMessageFor(model => model.input.NAME, null, new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.input.AMOUNT, "Amount")
#Html.TextBoxFor(model => model.input.AMOUNT, new { #style = "border-radius:3px;", #type = "text", #class = "form-control", #placeholder = Html.DisplayNameFor(m => m.input.AMOUNT), #autocomplete = "on" })
#Html.ValidationMessageFor(model => model.input.AMOUNT, null, new { #class = "text-danger" })
</div>
</div>
<div class="col-md-6">
<div>
#Html.LabelFor(model => model.input.CURRENCY_ID, "Currency")
#*#Html.DropDownList("CURRENCY_ID", (IEnumerable<SelectListItem>)ViewBag.name, "Please Select a Currency", new { #class = "form-control", #style = "border-radius:3px;" })*#
#Html.DropDownListFor(x => x.input.CURRENCY_ID, Model.CurrenciesList, "Please Select a Currency", new { #class = "form-control", #style = "border-radius:3px;" })
#Html.ValidationMessageFor(model => model.input.CURRENCY_ID, null, new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.input.FEE_TYPE_ID, "Fee Type")
#Html.DropDownListFor(model => model.input.FEE_TYPE_ID, Model.FeeTypesList, "Please Select a Fee Type", new { #class = "form-control", #style = "border-radius:3px;" })
#Html.ValidationMessageFor(model => model.input.FEE_TYPE_ID, null, new { #class = "text-danger" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="panel-title">
<div class="form-actions no-color">
<input type="submit" value="Create" class="btn btn-success" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
</div>
}
When I clicked on the View (Create), I got this error
The CurrencyID is a DropDownList coming from CURRENCIES model class.
I have these questions:
Why am I getting this error and how do I resolve it.
How do I do ViewModel without mapping.?

Why am I getting this error and how do I resolve it.
Because the Model is not set in your view. It is null.
When the users visit the Create page, you need to make sure to present them with options in the dropdown. Therefore, you need to make sure you pass the model into the view during GET.
public ActionResult Create()
{
// your code and pass fees to your view.
return View(fees);
}
How do I do ViewModel without mapping. Any example please.
You can use AutoMapper NuGet package to do the mapping.

Related

Updating table issue in ASP.NET MVC

I have an ASP.NET MVC model class like this:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Customer
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Customer()
{
this.Rates_Comments = new HashSet<Rates_Comments>();
}
[Required]
public double ID { get; set; }
[Required]
public string Marital_Status { get; set; }
[Required]
public string Gender { get; set; }
[Required]
[Range(5000,500000)]
public double Income { get; set; }
[Required]
public double Children { get; set; }
[Required]
public string Education { get; set; }
[Required]
public string Occupation { get; set; }
[Required]
public string Home_Owner { get; set; }
View:
<h2>Update My Account:</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-inline">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group" style="width:380px;">
<div class="form-group">
#Html.Label("Email-User Name", htmlAttributes: new { #class = "control-label col-md-10" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control", #style = "width:220px", #readonly = "readonly" } })
<br />
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("First Name", htmlAttributes: new { #class = "control-label col-md-10" })
<div class="col-md-10">
#Html.EditorFor(model => model.F_Name, new { htmlAttributes = new { #class = "form-control", #style = "width:220px" } })
<br />
#Html.ValidationMessageFor(model => model.F_Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("Last Name", htmlAttributes: new { #class = "control-label col-md-10" })
<div class="col-md-10">
#Html.EditorFor(model => model.L_Name, new { htmlAttributes = new { #class = "form-control", #style = "width:220px" } })
<br />
#Html.ValidationMessageFor(model => model.L_Name, "", new { #class = "text-danger" })
</div>
</div>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,Marital_Status,Gender,Income,Children,Education,Occupation,Home_Owner,Cars,Commute_Distance,Region,Age,Buy,OrderNumber")] Customer customer)
{
int[] Children = new int[] { 0, 1, 2, 3, 4, 5 };
ViewBag.OrderNumber = new SelectList(db.Orders, "OrderNumber", "OrderNumber");
ViewBag.Gender = new SelectList(db.Customers.Select(x => x.Gender).Distinct());
ViewBag.email = new SelectList(db.Customers.Select(x => x.Email).Distinct());
ViewBag.fn = new SelectList(db.Customers.Select(x => x.F_Name).Distinct());
ViewBag.ln = new SelectList(db.Customers.Select(x => x.L_Name).Distinct());
ViewBag.pas = new SelectList(db.Customers.Select(x => x.Pass).Distinct());
ViewBag.Marital_Status = new SelectList(db.Customers.Select(x => x.Marital_Status).Distinct());
ViewBag.Education = new SelectList(db.Customers.Select(x => x.Education).Distinct());
ViewBag.Occupation = new SelectList(db.Customers.Select(x => x.Occupation).Distinct());
ViewBag.Home_Owner = new SelectList(db.Customers.Select(x => x.Home_Owner).Distinct());
ViewBag.Cars = new SelectList(db.Customers.Select(x => x.Cars).Distinct());
ViewBag.Commute_Distance = new SelectList(db.Customers.Select(x => x.Commute_Distance).Distinct());
ViewBag.Region = new SelectList(db.Customers.Select(x => x.Region).Distinct());
ViewBag.Children = new SelectList(Children);
if (ModelState.IsValid)
{
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.OrderNumber = new SelectList(db.Orders, "OrderNumber", "OrderNumber", customer.OrderNumber);
return View(customer);
}
My issue that because of the [Required] data annotations, I can't update one cell in my table for example, user have to access his account to edit it if he needs to, so he may only edit one filed, not all of it.
And due registration issue, all filed are required, so how to overcome this one?

MVC - Foreign Key Error because of ViewModel?

I am Creating View Model of Employee Class and strongly typed my Create View with the EmployeeViewModel. In future, I will add many classes in my View Model. But the problem is I am getting Gender Foreign Key Error. May be I am binding wrong values in Create Controller. Below is my code:
Create Controllers:
public ActionResult Create()
{
ViewBag.GenderId = new SelectList(db.Genders, "Id", "Name");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(EmployeeViewModel employeeModel)
{
if (ModelState.IsValid)
{
db.Employees.Add(employeeModel.Employee);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.GenderId = new SelectList(db.Genders, "Id", "Name", employeeModel.Employee.GenderId);
return View(employeeModel);
}
Create View:
#model WebApplication2.EmployeeViewModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Employee</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Employee.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Employee.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Employee.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Employee.GenderId, "GenderId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("GenderId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Employee.GenderId, "", new { #class = "text-danger" })
</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>
}
Models:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public byte GenderId { get; set; }
public Gender Gender { get; set; }
}
public class Gender {
public byte Id { get; set; }
public string Name { get; set; }
}
View Model:
public class EmployeeViewModel
{
public Employee Employee { get; set; }
}

i would like to populate one drop down list using another drop down list

i tried a code from a video and got an error :
This is the Error when i click my drop down to display the states from country
this is my controller code:
public ActionResult Submit()
{
List<Country> allCountry = new List<Country>();
List<State> allState = new List<State>();
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
}
ViewBag.CountryID = new SelectList(allCountry, "CountryID", "CountryName");
ViewBag.StateID = new SelectList(allState, "StateID", "StateName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken] // this is for prevent CSRF Attack
public ActionResult Submit(Feedback fb)
{
List<Country> allCountry = new List<Country>();
List<State> allState = new List<State>();
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allCountry = dc.Countries.OrderBy(a => a.CountryName).ToList();
if (fb != null && fb.CountryID > 0)
{
allState = dc.States.Where(a => a.CountryID.Equals(fb.CountryID)).OrderBy(a => a.StateName).ToList();
}
}
ViewBag.CountryID = new SelectList(allCountry, "CountryID", "CountryName", fb.CountryID);
ViewBag.StateID = new SelectList(allState, "StateID", "StateName", fb.StateID);
if (ModelState.IsValid)
{
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
dc.Feedbacks.Add(fb);
dc.SaveChanges();
ModelState.Clear();
fb = null;
ViewBag.Message = "Successfully submitted";
}
}
else
{
ViewBag.Message = "Failed! Please try again";
}
return View(fb);
}
[HttpGet]
public JsonResult GetStates(string countryID = "")
{
List<State> allState = new List<State>();
int ID = 0;
if (int.TryParse(countryID, out ID))
{
using (DropDownTestEntities1 dc = new DropDownTestEntities1())
{
allState = dc.States.Where(a => a.CountryID.Equals(ID)).OrderBy(a => a.StateName).ToList();
//allState = dc.States.Where(a => a.CountryID.Equals(ID)).OrderBy(a => a.StateName).ToList();
}
}
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
}
this is my model code :
public partial class Feedback
{
public int FeedbackID { get; set; }
[Display(Name = "Full Name")]
[Required(ErrorMessage = "Please provide your fullname", AllowEmptyStrings = false)]
public string FullName { get; set; }
[Display(Name = "Mobile No")]
public string MobileNo { get; set; }
[Display(Name = "Country")]
[Required(ErrorMessage = "Please select country", AllowEmptyStrings = false)]
public int CountryID { get; set; }
[Display(Name = "State")]
[Required(ErrorMessage = "Please select state", AllowEmptyStrings = false)]
public int StateID { get; set; }
}
and this is my view with my ajax code :
#using (Html.BeginForm("Submit", "Feedback", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<fieldset>
<legend>Feedback</legend>
#if (ViewBag.Message != null)
{
<div style="border:solid 1px black">
#ViewBag.Message
</div>
}
<div class="editor-label">
#Html.LabelFor(model => model.FullName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FullName)
#Html.ValidationMessageFor(model => model.FullName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MobileNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MobileNo)
#Html.ValidationMessageFor(model => model.MobileNo)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CountryID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.CountryID, #ViewBag.CountryID as SelectList, "Select Country")
#Html.ValidationMessageFor(model => model.CountryID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StateID)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.StateID, #ViewBag.StateID as SelectList, "Select State")
#Html.ValidationMessageFor(model => model.StateID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript">
$(document).ready(function () {
$("#CountryID").change(function () {
// this will call when Country Dropdown select change
var countryID = parseInt($("#CountryID").val());
if (!isNaN(countryID)) {
var ddState = $("#StateID");
ddState.empty(); // this line is for clear all items from State dropdown
ddState.append($("<option></option").val("").html("Select State"));
// Here I will call Controller Action via Jquery to load State for selected Country
$.ajax({
url: "#Url.Action("GetStates","Feedback")",
type: "GET",
data: { countryID: countryID },
dataType: "json",
success: function (data) {
$.each(data, function (i, val) {
ddState.append(
$("<option></option>").val(val.StateID).html(val.StateName)
);
});
},
error: function () {
alert("Error!");
}
});
}
});
});
</script>
}
All i want is for my country selecteditem to populate my state with the link between the two. E.g. if i select South Africa, it must only display Gauteng, Cape Town etc.
Please can your'll help me with my error or provide guidance thanks.
Issue 1: Try using == instead of using .Equals() because if CountryIDis null, you'll throw an error.
Issue 2: Change
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
to
return Json(allState, JsonRequestBehavior.AllowGet);
Possible Issue 3?
Try this as your success function:
success: function (data) {
$(data).each(function () {
ddState.append(
$("<option></option>").val(this.StateID).html(this.StateName)
);
});
},

Save an image to a database in MVC 4

I am trying to get an image file name and location saved into a database, using mvc 4. Can someone see where I am going wrong? I am only new to mvc, and building this for a client. I have bplace a break point on this line "if (Request.Files.Count > 0)", but it skips it and goes into my else statement.
public ActionResult Create2(FestivalVM model)
{
if (ModelState.IsValid != true)
{
if (model.SelectedFestivalType != -1)
{
//db.save stuff from create.
Festival Newfestival = new Festival();
Newfestival.EndDate = model.endDate.Date;
Newfestival.FestivalCounty = db.Counties.Where(p => p.ID == model.SelectedCounty).Single();
Newfestival.FestivalName = model.FestivalName;
Newfestival.Description = model.sDescription;
Newfestival.FType = db.FestivalTypes.Where(p => p.ID == model.SelectedFestivalType).Single();
Newfestival.StartDate = model.startDate.Date;
Newfestival.Location = model.Location;
Newfestival.FestivalTown = db.Towns.Where(p => p.ID == model.SelectedTown).Single();
Newfestival.UserID = WebSecurity.CurrentUserId;
if (Request.Files.Count > 0)
{
string fileName = Guid.NewGuid().ToString();
string serverPath = Server.MapPath("~\\Content\\FestivalLogo");
Bitmap newImage = new Bitmap(Request.Files[0].InputStream);
newImage.Save(serverPath + "\\" + fileName + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
model.festivalLogo = "Content/FestivalLogo/" + fileName + ".jpg";
db.Festivals.Add(Newfestival);
db.SaveChanges();
return RedirectToAction("Details", new {id = Newfestival.FestivalId});
}
else
{
db.Festivals.Add(Newfestival);
db.SaveChanges();
return RedirectToAction("Details", new { id = Newfestival.FestivalId });
}
}
ModelState.AddModelError("", "No Festival Type Picked");
}
model.County = db.Counties.ToDictionary(p => p.ID, q => q.Name);
model.FestivalType = db.FestivalTypes.ToDictionary(p => p.ID, q => q.FType);
model.FestivalType.Add(-1, "--- Add New Festival Type ---");
model.Towns = db.Towns.ToDictionary(p => p.ID, q => q.Name);
model.startDate = DateTime.Now;
model.endDate = DateTime.Now;
return View(model);
}
View- Edited Here
#model MyFestival.Models.FestivalVM
#{
ViewBag.Title = "Add a Festival";
Layout = "~/Views/Shared/Festival.cshtml";
}
<h2>Create Your Festival</h2>
<br />
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<ol class="breadcrumb">
<li>Home</li>
<li class="active">Creating a Festival</li>
</ol>
<hr />
#Html.ValidationSummary(true, null, new{#class="alert alert-danger"})
<div class="form-group">
#Html.LabelFor(model => model.FestivalName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-info-sign"></i></span>
#Html.TextBoxFor(model => model.FestivalName, new { #class = "form-control", #style = "width:210px" })
</div>
#Html.ValidationMessageFor(model => model.FestivalName, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.startDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(model => model.startDate, new { #class = "form-control datepicker", #style = "width:250px" })
</div>
#Html.ValidationMessageFor(model => model.startDate, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.endDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(model => model.endDate, new { #class = "form-control datepicker", #style = "width:250px" })
</div>
<!--<input class="form-control datepicker" style="width:250px" name="endDate" placeholder="Please pick date..."/>-->
#Html.ValidationMessageFor(model => model.endDate, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Towns, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-tag"></i></span>
#Html.DropDownListFor(p => p.SelectedTown, Model.Towns.Select(p => new SelectListItem()
{
Text = p.Value.ToString(),
Value = p.Key.ToString(),
Selected = false
}),
new
{
#class = "form-control",
#style = "width:210px",
placeholder = "---- Select a Town ----"
})
</div>
#Html.ValidationMessageFor(model => model.Towns, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.County, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-tag"></i></span>
#Html.DropDownListFor(p => p.SelectedCounty, Model.County.Select(p => new SelectListItem()
{
Text = p.Value.ToString(),
Value = p.Key.ToString(),
Selected = false
}),
new
{
#class = "form-control",
#style = "width:210px"
})
</div>
#Html.ValidationMessageFor(model => model.County, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FestivalType, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-tag"></i></span>
#Html.DropDownListFor(p => p.SelectedFestivalType, Model.FestivalType.Select(p => new SelectListItem()
{
Text = p.Value.ToString(),
Value = p.Key.ToString(),
Selected = false
}),
new
{
#class = "form-control",
#style = "width:210px;",
#onchange = "checkaddnew();"
})
</div>
#Html.ValidationMessageFor(model => model.FestivalType, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.sDescription, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-info-sign"></i></span>
#Html.TextAreaFor(model => model.sDescription, new { #class = "form-control", #style = "width:210px;" })
</div>
#Html.ValidationMessageFor(model => model.sDescription, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Location, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-info-sign"></i></span>
#Html.TextAreaFor(model => model.Location, new { #class = "form-control", #style = "width:210px" })
</div>
#Html.ValidationMessageFor(model => model.Location, null, new { #style = "color:red;" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.festivalLogo, new{#class="control-label col-md-2"})
<div class="col-md-10">
<input type="file" id="imageFile" name="imageFile" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-info" />
#Html.ActionLink("Back to List", "Index", null, new { #class = "btn btn-danger" })
</div>
</div>
</div>
}
#Html.Partial("CreateFestivalType", new MyFestival.Models.FestivalTypeVM())
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function () {
$('#SelectedFestivalType').change(function () {
if ($(this).find(":selected").val() == -1) {
$('#myModal').modal('show');
}
});
});
</script>
<script type="text/javascript">
function ajaxResponse(data) {
alert("This Worked and the Data ID is: " + data.FestivalTypeID);
var newOption = "<option value='" + data.FestivalTypeID + "'>" + data.Name + "</option>";
$('#SelectedFestivalType').append(newOption);
$('#myModal').modal('hide');
$("#SelectedFestivalType option[value='" + data.FestivalTypeID + "']").attr("selected", "selected");
}
;
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#startDate").datepicker("setDate", '+1', { dateFormat: "dd/mm/yy" }).on('changeDate', function (ev) {
$(this).blur();
$(this).datepicker('hide');
});
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#endDate").datepicker("setDate", '+2', { dateFormat: "dd/mm/yy" }).on('changeDate', function (ev) {
$(this).blur();
$(this).datepicker('hide');
});
});
</script>
Model
public class Festival
{
[Key]
public int FestivalId { get; set; }
[Required]
[Display(Name = "Festival Name"), StringLength(100)]
[DisplayFormat(ApplyFormatInEditMode = true)]
public string FestivalName { get; set; }
[Required]
[Display(Name = "Start Date")/*, DataType(DataType.Date)*/]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime StartDate { get; set; }
[Required]
[Display(Name = "End Date")/*, DataType(DataType.Date)*/]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime EndDate { get; set; }
[Display(Name = "Festival Location")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public DbGeography Location { get; set; }
[Required]
[Display(Name = "County")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public virtual County FestivalCounty { get; set; }
[Required]
[Display(Name = "Town")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public virtual Town FestivalTown { get; set; }
[Required]
[Display(Name = "Festival Type")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public virtual FestivalType FType { get; set; }
[Display(Name = "Festival Logo")]
[DataType(DataType.Upload)]
[DisplayFormat(ApplyFormatInEditMode = true)]
public string FestivalLogo { get; set; }
[Display(Name = "Description"), StringLength(200)]
public string Description { get; set; }
public ICollection<Events> Events { get; set; }
public IEnumerable<Events> EventsOrdered
{
get { return Events.OrderBy(e => e.EventsDate); }
}
public int UserID { get; set; }
[ForeignKey("UserID")]
public virtual UserProfile User { get; set; }
}
ViewModel
public class FestivalVM
{
public int FestivalID { get; set; }
[Required]
[Display(Name = "Town")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public Dictionary<int, string> Towns { get; set; }
[Required]
[Display(Name = "County")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public Dictionary<int, string> County { get; set; }
[Required]
[Display(Name = "Festival Type")]
[DisplayFormat(ApplyFormatInEditMode = true)]
public Dictionary<int, string> FestivalType { get; set; }
public int SelectedTown { get; set; }
public int SelectedCounty { get; set; }
public int SelectedFestivalType { get; set; }
[Required]
[Display(Name = "Festival Name"), StringLength(100)]
[DisplayFormat(ApplyFormatInEditMode = true)]
public string FestivalName { get; set; }
[Required]
[Display(Name = "Start Date")/*, DataType(DataType.Date)*/]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime startDate { get; set; }
[Required]
[Display(Name = "End Date")/*, DataType(DataType.Date)*/]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime endDate { get; set; }
public HttpPostedFileWrapper imageFile { get; set; }
[Display(Name = "Festival Logo")]
public string festivalLogo { get; set; }
public UserProfile UserID { get; set; }
[Display(Name = "Description"), StringLength(200)]
public string sDescription { get; set; }
[Required]
[Display(Name = "Location")]
public DbGeography Location { get; set; }
}
You can do some changes to allow posting data:
View
change #using (Html.BeginForm()) to this line: using (Html.BeginForm("Create2", "YourControllerName", FormMethod.Post, new {enctype="multipart/form-data"})) as you are posting data
Action
should be like this:
public ActionResult Create2(FestivalVM model, HttpPostedFileBase imageFile)
{
if (ModelState.IsValid != true)
{
if (model.SelectedFestivalType != -1)
{
//db.save stuff from create.
Festival Newfestival = new Festival();
Newfestival.EndDate = model.endDate;
Newfestival.FestivalCounty = db.Counties.Where(p => p.ID == model.SelectedCounty).Single();
Newfestival.FestivalName = model.FestivalName;
Newfestival.Description = model.sDescription;
Newfestival.FType = db.FestivalTypes.Where(p => p.ID == model.SelectedFestivalType).Single();
Newfestival.StartDate = model.startDate;
Newfestival.Location = model.Location;
Newfestival.FestivalTown = db.Towns.Where(p => p.ID == model.SelectedTown).Single();
Newfestival.UserID = WebSecurity.CurrentUserId;
if (Request.Files.Count > 0)
{
string fileName = Guid.NewGuid().ToString();
string serverPath = Server.MapPath("~\\Content\\FestivalLogo");
Bitmap newImage = new Bitmap(Request.Files["imageFile"].InputStream);
newImage.Save(serverPath + "\\" + fileName + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
Newfestival.festivalLogo = "Content/FestivalLogo/" + fileName + ".jpg";
db.Festivals.Add(Newfestival);
db.SaveChanges();
return RedirectToAction("Details", new {id = Newfestival.FestivalId});
}
else
{
db.Festivals.Add(Newfestival);
db.SaveChanges();
return RedirectToAction("Details", new { id = Newfestival.FestivalId });
}
}
ModelState.AddModelError("", "No Festival Type Picked");
}
model.County = db.Counties.ToDictionary(p => p.ID, q => q.Name);
model.FestivalType = db.FestivalTypes.ToDictionary(p => p.ID, q => q.FType);
model.FestivalType.Add(-1, "--- Add New Festival Type ---");
model.Towns = db.Towns.ToDictionary(p => p.ID, q => q.Name);
model.startDate = DateTime.Now;
model.endDate = DateTime.Now;
return View(model);
}
I hope it will help

Using Automapper to Edit selected fields of a model MVC4

I am trying to update selected fields using a viewmodel(OApplyIDViewModel) of the original model(OApply). When I run changes are not effected. I will appreciate help from anyone who is experienced with this. I do not get any error. The form submits and redirects.
I have this at global.asax
AutoMapper.Mapper.CreateMap<OApplyIDViewModel, OApply>();
This is ViewModel
public class OApplyIDViewModel
{
[Key]
public int OAId { get; set; }
[Display(Name = "Identification")]
[Required(ErrorMessage = "Identification Required")]
public int IdId { get; set; }
[Display(Name = "Identification Number")][Required(ErrorMessage="ID Number Required")]
public string AIdentificationNo { get; set; }
[Display(Name = "Licence Version(5b)")]
[RequiredIf("IdId", Comparison.IsEqualTo, 1, ErrorMessage = "Version(5b) Required")]
public string ALicenceVersion { get; set; }
public int CountryId { get; set; }
[RequiredIf("IdId",Comparison.IsNotEqualTo,1, ErrorMessage="Country Required")]
[Display(Name = "Your Electronic Signature Date Seal")]
[Required(ErrorMessage="Date Signature Seal Required")]
public DateTime SigDate { get; set; }
[ScaffoldColumn(false)]
[Display(Name = "Last Updated on")]
public DateTime UDate { get; set; }
[ScaffoldColumn(false)]
[Display(Name = "Last Updated by")]
public String UDateBy { get; set; }
}
This is at Controller
//GET
public ActionResult ClientEditID(int id)
{
var model = new OApplyIDViewModel();
OApply oapply = db.OApply.Find(id);
if (model == null )
{
return HttpNotFound();
}
ViewBag.CountryId = new SelectList(db.Countries, "CountryId", "CountryName", model.CountryId);
ViewBag.IdId = new SelectList(db.PhotoIds, "IdId", "IdName", model.IdId);
return View();
}
[HttpPost]
public ActionResult ClientEditId(OApplyIDViewModel oapply, int Id)
{
if (!ModelState.IsValid)
{
return View(oapply);
}
var onlineid = db.OApply.Where(x => x.OAId == Id).FirstOrDefault();
Mapper.Map<OApplyIDViewModel,OApply>(oapply);
oapply.UDateBy = Membership.GetUser().ProviderUserKey.ToString();
oapply.UDate = DateTime.Now;
db.Entry(onlineid).State= EntityState.Modified;
db.SaveChanges();
ViewBag.CountryId = new SelectList(db.Countries, "CountryId", "CountryName", oapply.CountryId);
ViewBag.IdId = new SelectList(db.PhotoIds, "IdId", "IdName", oapply.IdId);
return RedirectToAction("HomeAccount");
}
This is the View
#using (Html.BeginForm("ClientEditId", "OApply", FormMethod.Post, new { enctype = "multipart/form-data", #class = "stdform" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>OnlineApplication</legend>
#Html.HiddenFor(model => model.OAId)
<div class="related">
<div class="editor-label">
#Html.LabelFor(model => model.IdId, "IdType")
</div>
<div class="editor-field">
#Html.DropDownList("IdId", String.Empty)
#Html.ValidationMessageFor(model => model.IdId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AIdentificationNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AIdentificationNo)
#Html.ValidationMessageFor(model => model.AIdentificationNo)
</div>
<div class="requiredfields">
<div class="editor-label">
#Html.LabelFor(model => model.ALicenceVersion)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ALicenceVersion)
#Html.ValidationMessageFor(model => model.ALicenceVersion)
</div>
</div>
<div class="country">
<div class="editor-label">
#Html.LabelFor(model => model.CountryId)
</div>
<div class="editor-field">
#Html.DropDownList("CountryId")
#Html.ValidationMessageFor(model => model.CountryId)
</div>
</div></div>
<div class="editor-label">
#Html.LabelFor(model => model.SigDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SigDate)
#Html.ValidationMessageFor(model => model.SigDate)
</div>
<p>
<input type="submit" value="Save" />
</p>
There is something wrong here:
var onlineid = db.OApply.Where(x => x.OAId == Id).FirstOrDefault();
-> Mapper.Map<OApplyIDViewModel,OApply>(oapply);
oapply.UDateBy = Membership.GetUser().ProviderUserKey.ToString();
oapply.UDate = DateTime.Now;
db.Entry(onlineid).State= EntityState.Modified;
The line with the arrow returns a new OApply instance. It does not update onlineid. In fact, it has no idea about onlineid. Try the following.
Mapper.Map<OApplyIDViewModel,OApply>(oapply, onlineid);
Now it will modify onlineid instead of returning one. However, you should ignore the mapping for the primary key if it is an identity (auto-incrementing) one.
AutoMapper.Mapper.CreateMap<OApplyIDViewModel, OApply>()
.ForMember(dest => dest.OAId, opt => opt.Ignore());
I am not sure if OAId is your primary key or not. You are not following naming conventions and probably some other conventions too, at all.
I have made corrections in your code :
public ActionResult ClientEditID(int id)
{
OApply oapply = db.OApply.Find(id);
->if (oapply == null )
{
return HttpNotFound();
}
->var model = Mapper.Map<OApply, OApplyIDViewModel>(oapply);
ViewBag.CountryId = new SelectList(db.Countries, "CountryId", "CountryName", model.CountryId);
ViewBag.IdId = new SelectList(db.PhotoIds, "IdId", "IdName", model.IdId);
->return View(model);
}
Your HttpPost is mostly valid, except that you put data into ViewBag before you use RedirectToAction(). That data will be lost. Instead, use TempData dictionary. Check msdn.