MVC save image to DB (with EF) - sql

I am still new to MVC and am struggling with uploading an image to a DB in my web application. I've seen tons of articles on the subject, followed instructions but still I am stuck with the following error message:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
Whenever I use [Bind(Exclude = "CompetitionPicture")], everything would work fine, except for, of course, the "CompetitionPicture" won't be included.
My ViewModel looks as follows:
public class PhotoCompetition
{
public int ID { get; set; }
public string UserID { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
public byte[] CompetitionPicture { get; set; }
[Required]
[Display(Name = "by checking this box I accept the Terms & Conditions")]
public bool TermsAndConditionsAccepted { get; set; }
public DateTime TimeStamp { get; set; }
}
Controller is as follows:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadCompetitionPicture(/*[Bind(Exclude = "CompetitionPicture")]*/ PhotoCompetition model)
{
string test = Request.Form["CompetitionPicture"];
byte[] bt = Convert.FromBase64String(test.Split(',')[1]);
var participation = new PhotoCompetition
{
CompetitionPicture = bt
};
// var participation = new PhotoCompetition
// {
// UserID = User.Identity.GetUserId(),
// Email = User.Identity.GetUserName(),
// TermsAndConditionsAccepted = model.TermsAndConditionsAccepted,
// TimeStamp = DateTime.UtcNow.ToUniversalTime()
// };
// participation.CompetitionPicture = competitionPicture;
// DB.PhotoCompetition.Add(model);
// DB.SaveChanges();
// return RedirectToAction("Index");
//}
return View(model);
}
and the View:
<section id="photoCompetition" class="manageForm">
#using (Html.BeginForm("UploadCompetitionPicture", "errandom", FormMethod.Post, new { #id = "photoCompetitionForm", #class = "form-horizontal", #role = "form", #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div id="photoCompetitionSection" class="manageSection">
<p id="photoCompetitionSectionTitle" class="manageSectionTitle">
Upload your picture and be selected as our model!
</p>
#Html.HiddenFor(m => m.UserID)
#Html.HiddenFor(m => m.Email)
#Html.HiddenFor(m => m.FirstName)
#Html.HiddenFor(m => m.TimeStamp)
<div id="photoCompetitionProfilePictureArea" class="manageArea row">
#Html.LabelFor(m => m.CompetitionPicture, new { #id = "photoCompetitionProfilePictureLabel", #class = "manageLabel col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-3 col-lg-offset-1 col-lg-4" })
<a id="photoCompetitionProfilePictureSelectionButton" class="manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset0 col-md-7 col-lg-offset-0 col-lg-6" href="#">
select a file...
</a>
#Html.TextBoxFor(m => m.CompetitionPicture, new { #id = "photoCompetitionProfilePictureField", #class = "manageField col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-0 col-md-7 col-lg-offset-0 col-lg-6", #name = "CompetitionPicture", #type = "file", #style = "display: none" })
</div>
<div id="photoCompetitionTermsAndConditionsArea" class="manageArea row">
#Html.CheckBoxFor(m => m.TermsAndConditionsAccepted, new { #id = "photoCompetitionTermsAndConditionsField", #class = "photoCompetitionTermsAndConditionsField" })
#Html.LabelFor(m => m.TermsAndConditionsAccepted, new { #id = "photoCompetitionTermsAndConditionsLabel", #class = "photoCompetitionTermsAndConditionsLabel" })
</div>
<script>
jQuery("#photoCompetitionProfilePictureSelectionButton").click(function () {
$("#photoCompetitionProfilePictureField").click();
});
</script>
<script>
$("#photoCompetitionProfilePictureField").change(function () {
var fullFileName = $("#photoCompetitionProfilePictureField").val()
$("#photoCompetitionProfilePictureSelectionButton").html(fullFileName.substr(fullFileName.lastIndexOf('\\') + 1));
});
</script>
<div id="photoCompetitionButtonArea" class="manageArea row">
<input id="photoCompetitionButtonUpload" class="manageButton col-xs-offset-1 col-xs-10 col-sm-offset-1 col-sm-10 col-md-offset-1 col-md-10 col-lg-offset-1 col-lg-10" type="submit" value="Save" />
</div>
</div>
}
</section>
Your support is highly appreciated!

I'm stuck in this issue for days before, i will put simple solving.
first: I save image path as string in DB not byte
and Image File as HttpPostedFileBase in model Like :`
public string ProductImage { get; set; }
[Required(ErrorMessage = "Image is required")]
public HttpPostedFileBase ImageFile { get; set; }
in view you will write :
<div class="form-group">
<div class="col-md-10">
<input type="file" name="ImageFile" required />
</div>
#Html.ValidationMessageFor(model => model.ImageFile, "", new { #class = "text-danger" })
</div>
name of input must be like the name in model and here I named it ImageFile
in controller will write
public void SaveImage(Product pro)
{
string fileName = Path.GetFileNameWithoutExtension(pro.ImageFile.FileName);
string exetention = Path.GetExtension(pro.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + exetention;
pro.ProductImage = "~/ProductDropBox/" + fileName;
fileName = Path.Combine(Server.MapPath("~/ProductDropBox/"), fileName);
pro.ImageFile.SaveAs(fileName);
}
I use this function to save image in DB and in Folder created for images
finally in action result you will write :
public ActionResult AddProducts(Product pro)
{
if (ModelState.IsValid)
{
SetCategories();
SaveImage(pro);
pro.UPID = Guid.NewGuid();
using (db)
{
db.Products.Add(pro);
db.SaveChanges();
}
return RedirectToAction("Index");
}
else
{
return View("AddProducts",pro);
}
}
I hope this useful

Related

How to solve empty model trouble using both Ajax.BeginForm and Html.BeginForm in MVC

I am new to MVC and stuck in passing modal to controller.
I have read many similar threads in SO, to no avail.
Here, I have a view for entering order details.
User will enter order item details (using ajax.BeginForm) and when he clicks save, whole order will be saved in backend (using Html.BeginForm). Ajax.BeginForm is working properly and passing + displaying records properly. But Html.BeginForm is passing model as nothing.
Here is my code ...
My Models
public class OrderItemsModel
{
public string SrNo { get; set; }
public int? ItemCode { get; set; }
public string ItemName { get; set; }
public Decimal? Qty { get; set; }
public Decimal? Rate { get; set; }
public Decimal? Amount { get; set; }
}
public class OrderModel
{
public string OrderNumber { get; set; }
public string OrderDate { get; set; }
public int? CustomerCode { get; set; }
public string CustomerName { get; set; }
public string Note { get; set; }
//List of items selected in Order
public List<OrderItemsModel> ItemsSelected { get; set; }
}
Extract from My View
#model OrderApplication.Models.OrderModel
#{
ViewBag.Title = "Index";
Model.ItemsSelected = ViewBag.getlist;
}
#using (Ajax.BeginForm("UpdateItemList", "Order", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "selectedtable" }))
{
<h2 style="margin-left:5%;">Order Entry</h2>
//Order No & Date
<div class="row">
<div class="col-sm-6">
<div class="col-sm-3">
#Html.LabelFor(model => model.OrderNumber, "OrderNo"):
</div>
<div class="col-sm-3">
#Html.TextBoxFor(model => model.OrderNumber, new { #class = "form-control", #readonly = "readonly" })
</div>
</div>
<div class="col-sm-6">
<div class="col-sm-3">
#Html.LabelFor(model => model.OrderDate, "Date"):
</div>
<div class="col-sm-3">
#Html.TextBoxFor(model => model.OrderDate, new { #class = "form-control" })
</div>
</div>
</div>
<br />
//Table of entries
<div id="selectedtable">
#Html.Partial("_selectTable", Model);
</div>
<br />
}
#*Main Save*#
<div class="row">
<div class="col-sm-12">
<div class="col-sm-3">
#using (Html.BeginForm("SaveData", "Order", new { order = Model, id = "loginform", #class = "justify-content-center" }))
{
<input type="submit" value="Save Order" class="btn btn-success" />
}
</div>
<div class="col-sm-3">
<input type="button" class="btn btn-success" value="Clear Form" onclick="location.href='#Url.Action("Clear", "Order")'" />
</div>
</div>
</div>
My Controller
public class OrderController : Controller
{
public List<OrderItemsModel> dd = new List<OrderItemsModel>() ;
[HttpPost]
public ActionResult SaveData(OrderModel order, string id)
{
if (order == null) //order is always Nothing
{
return View(order);
}
if (order.CustomerCode == 0)
{
return View(order);
}
return View(order);
}
}
}
You shouldn't use both Ajax.BeginForm and Html.BeginForm, as it won't work. Please, check this post as might be of help to decide which one you wish to choose:
https://forums.asp.net/t/1757936.aspx?When+to+use+Html+BeginForm+vs+ajax+BeginForm
If you still want to use Html.BeginForm, just move the using sentence to replace your Ajax.BeginForm at the top of the page, so the form covers all fields, and the model won't be empty.

Getting some input from user and insert multiple table with Entity Framework

I want to add some information into my database. The question is how can I post my inputs for 3 table at the same time? My tables are below. Let me clear that.
I have teachers and working hours and working days. I want that firstly I select the teacher name from dropdownlist,then select the day from dropdownlist and write working hours for example "09:00 - 17:00".
After that I submit these information I expectation is that seeing all these information can be added into database seperately and relationally.
Sample scenario: John Reese Friday 09:00-17:00
Harold Finch Monday 11:00-15:00
I am able to pull the teacher's names from database but at the same time in the same page I want to see that day's names. After all these selecetions as I mentioned above, I wanna add all these informations.
My create controller
public ActionResult Create()
{
var myTeacherList = (from teacher in db.Teachers.ToList()
select new SelectListItem
{
Text = teacher.Firstname + teacher.Lastname,
Value = teacher.Id.ToString(),
}).ToList();
var myDayNameList = (from day in db.WeekDays.ToList()
select new SelectListItem
{
Text = day.Name,
Value = day.Id.ToString(),
}).ToList();
ViewBag.TeacherId = myTeacherList;
ViewBag.DayId = myDayNameList;
return View();
}
My Create Controller
<div class="form-horizontal">
<h4>Appointment</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TeacherId, "Teacher Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m=>m.Teacher.Id,(List<SelectListItem>)ViewBag.TeacherId, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TeacherId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Hours,"Working Hour", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Hours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Hours, "", 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>
}
Teacher.cs
namespace LanguageSchool.Models
{
using System;
using System.Collections.Generic;
public partial class Teacher
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Teacher()
{
this.Appointments = new HashSet<Appointment>();
this.Classes = new HashSet<Class>();
this.Languages = new HashSet<Language>();
}
public int Id { get; set; }
public string Description { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public System.DateTime DateOfStart { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Appointment> Appointments { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Class> Classes { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Language> Languages { get; set; }
}
}
Appointment.cs
namespace LanguageSchool.Models
{
using System;
using System.Collections.Generic;
public partial class Appointment
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Appointment()
{
this.WeekDays = new HashSet<WeekDay>();
}
public int Id { get; set; }
public int TeacherId { get; set; }
public string Hours { get; set; }
public virtual Teacher Teacher { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<WeekDay> WeekDays { get; set; }
}
}
WeekDay.cs
namespace LanguageSchool.Models
{
using System;
using System.Collections.Generic;
public partial class WeekDay
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public WeekDay()
{
this.Class_WeekDay = new HashSet<Class_WeekDay>();
this.Appointments = new HashSet<Appointment>();
}
public int Id { get; set; }
public string Name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Class_WeekDay> Class_WeekDay { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Appointment> Appointments { get; set; }
}
}
We need to make a ViewModel that contains all those properties so that the moment we do a POST request, they are all bound and we could access them for saving.
But first we need to modify your models and insert a class for the many to many table.
We need to remove Weekday from Appointments and
Appointments from Weekday.
Then replace them with AppointmentWeekday. Be sure to run Migrations/Update-Database after this first step.
public class Appointment{
...
// REMOVE public virtual ICollection<WeekDay> WeekDays { get; set; }
// Add this
public virtual ICollection<AppointmentWeekday> AppointmentWeekdays {get;set;}
}
public class Weekday{
...
// REMOVE public virtual ICollection<Appointment> Appointments { get; set; }
// Add this
public virtual List<AppointmentWeekday> AppointmentWeekdays {get;set;}
}
// Add this
public class AppointmentWeekday{
public int AppointmentId {get;set;}
[ForeignKey("AppointmentId")]
public virtual Appointment Appointment {get;set;}
public int WeekdayId {get;set;}
[ForeignKey("WeekdayId")]
public virtual Weekday Weekday {get;set;}
}
Make the View Model with the necessary properties, I named it TeacherAppointmentViewModel.
public class TeacherAppointmentViewModel{
public int TeacherId {get;set;}
public int DayId {get;set;}
public string Hours {get;set;}
}
Instantiate this in your controller and pass it to the view.
public ActionResult Create()
{
var myTeacherList = (from teacher in db.Teachers.ToList()
select new SelectListItem
{
Text = teacher.Firstname + teacher.Lastname,
Value = teacher.Id.ToString(),
}).ToList();
var myDayNameList = (from day in db.WeekDays.ToList()
select new SelectListItem
{
Text = day.Name,
Value = day.Id.ToString(),
}).ToList();
ViewBag.TeacherId = myTeacherList;
ViewBag.DayId = myDayNameList;
// instantiate
TeacherAppointmentViewModel tvm = new TeacherAppointmentViewModel();
// pass to the view
return View(tvm);
}
Make your view use TeacherAppointmentViewModel.
#model TeacherAppointmentViewModel
Edit view, use the code below.
<div class="form-horizontal">
<h4>Appointment</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TeacherId, "Teacher Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m=>m.TeacherId,(List<SelectListItem>)ViewBag.TeacherId, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TeacherId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.WeekdayId, "Day", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m=>m.WeekdayId,(List<SelectListItem>)ViewBag.WeekdayId, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.WeekdayId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Hours,"Working Hour", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Hours, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Hours, "", 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>
Use controller action below, we need to assign the properties to Appointment and AppointmentWeekday then add to the db;
[HttpPost]
public ActionResult Create(TeacherAppointmentViewModel tvm){
// create appointment
Appointment a = new Appointment();
// assign teacher id and hours from viewmodel
a.TeacherId = tvm.TeacherId;
a.Hours = tvm.Hours;
// save appointment
db.Appointments.Add(a);
db.SaveChanges();
// create appointmentweekday
AppointmentWeekday aw = new AppointmentWeekday();
// assign properties
// since we've saved the appointment, we could use a.AppointmentId
aw.WeekdayId = tvm.WeekdayId;
aw.AppointmentId = a.AppointmentId; // appointment from earlier
// save appointmentweekday
db.AppointmentWeekdays.Add(aw);
db.SaveChanges();
}

mvc model fileupadload does not send model data

I have a mvc 5 asp.net file upload that upload pictures and create path for them.
File uploaded successfully, but model data does comes in null.
This is my model:
[Table("Slider")]
public partial class Slider
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Slider()
{
Slider1 = new HashSet<Slider>();
}
public int ID { get; set; }
public string Path { get; set; }
public int? Slider_ID { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Slider> Slider1 { get; set; }
}
This is Controller part:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Path")] Slider slider, List<HttpPostedFileBase> FileContent)
{
if (ModelState.IsValid)
{
byte[] imageData = null;
if (Request.Files.Count > 0)
{
HttpPostedFileBase poImgFile = Request.Files["Path"];
using (var binary = new BinaryReader(poImgFile.InputStream))
{
imageData = binary.ReadBytes(poImgFile.ContentLength);
}
}
string picturePath = string.Format(Server.MapPath("~/content/slider/{0}.jpg"), slider.ID);
CreateDirectory(picturePath);
using (FileStream writer = new FileStream(picturePath, FileMode.Create))
{
writer.Write(imageData, 0, imageData.Length);
}
db.Sliders.Add(slider);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(slider);
}
And this is the view:
#using (Html.BeginForm("Create", "Sliders", FormMethod.Post, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-12 form-group">
<div class="row">
#Html.LabelFor(model => model.Path, "Picture", htmlAttributes: new { #class = "control-label col-12 col-md-2" })
<div class="col-12 col-md-10">
<input type="file" name="Path" id="fileUpload" accept=".png,.jpg,.jpeg,.gif" />
#Html.ValidationMessageFor(model => model.Path, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-12 text-left">
<input type="submit" value="create" class="btn btn-success" /> | #Html.ActionLink("back to list", "Index", null, new { #class = "btn btn-primary" })
</div>
</div>
</div>
}
When I check my database I see that Path is :
System.Web.HttpPostedFileWrapper
and Slider_ID is null and Slider_ID1 is null too.
Any suggestions?
After searching my previous codes, I've found that, when saving changes to db in controller class, db.SaveChanges(); slider argument which had been sent to Create method, will get new ID.
I've added these 2 lines after if:
if (ModelState.IsValid)
{
db.Sliders.Add(slider);
db.SaveChanges();
and done my other business logic in lines after that.

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

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.

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