model post back with html attribute - asp.net-mvc

I am having an issue with getting the value back in my ViewModel after a postback using a JQuery datepicker. The post back has the correct date with the form group StartDate that does not have a new htmlAttribute attached to the EditorFor. The StopDate does not post back the selected date due to the htmlAttribute. I would prefer not to use a hidden field to send back the data since I know this should work. Anybody have any suggestions?
<div class="form-group" id="StartDate">
#Html.LabelFor(model => model.StartDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.reportTimeEntries[0].StartDate, "","StartDate" )
#Html.ValidationMessageFor(model => model.StartDate, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.StartDate)
</div>
</div>
<div class="form-group" id="StopDate">
#Html.LabelFor(model => model.StopDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.reportTimeEntries[0].StopDate, new { htmlAttributes = new { #class = "form-control date" } })
#Html.ValidationMessageFor(model => model.StopDate, "", new { #class = "text-danger" })
</div>
</div>
$('#StartDate .date').datepicker({
'format': 'mm/dd/yyyy',
'autoclose': true
});
$('#StopDate .date').datepicker({
'format': 'mm/dd/yyyy',
'autoclose': true
});
UPDATE
So it seems that this has worked by adding this to my ViewModel. The 'Nullable' section seems to allow the date to be posted back.
ViewModel
[DataType(DataType.DateTime)]
[Display(Name = "Stop Date")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> StopDate { get; set; }
View
<div class="form-group" id="StopDate">
#Html.LabelFor(model => model.StopDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.reportTimeEntries[0].StopDate, "","StopDate",new { htmlAttributes = new { #class = "form-control date" } })
#Html.ValidationMessageFor(model => model.StopDate, "", new { #class = "text-danger" })
</div>
</div>

Related

I tried Bootstrap DateTimePicker in ASP.NET MVC 5 but it's not working

I'm really new to ASP.NET MVC even the Web,I tried to build it on VS 2019,this is NOT the .net core project,it's the .NET for Win project,I tried to build a datetimepicker within the text input, so I tried to build to view like the below
#model log_viewer.Models.QueryParms
#{
ViewBag.Title = "QueryLog";
}
<h2>Query</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Query </h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.mdno, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.mdno, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.mdno, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.startdate, htmlAttributes: new { #class = "control-label col-md-2" })
#*<div class="col-md-10">
#Html.EditorFor(model => model.startdate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.startdate, "", new { #class = "text-danger" })
</div>*#
<div class="col-md-10">
<div class="input-group" id="datetimepicker">
#Html.EditorFor(model => model.startdate, new { htmlAttributes = new { #class = "datetimepicker form-control" } })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
#Html.ValidationMessageFor(model => model.startdate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.enddate, htmlAttributes: new { #class = "control-label col-md-2" })
#*<div class="col-md-10">
#Html.EditorFor(model => model.enddate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.enddate, "", new { #class = "text-danger" })
</div>*#
<div class="col-md-10">
<div class="input-group" id="datetimepicker">
#Html.EditorFor(model => model.enddate, new { htmlAttributes = new { #class = "form-control" } })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
#Html.ValidationMessageFor(model => model.enddate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Summit" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
My models are as below
public class QueryParms
{
[DisplayName("Contains Strings")]
public string mdno { get; set; }
[DisplayName("Begin Date")]
[DisplayFormat(DataFormatString = "{0:yyyy-mm-dd}", ApplyFormatInEditMode = true)]
public DateTime startdate { get; set; }
[DisplayName("End Date")]
[DisplayFormat(DataFormatString = "{0:yyyy-mm-dd}", ApplyFormatInEditMode = true)]
public DateTime enddate { get; set; }
}
When I clicked the datetime picker, it just not working, nothing happened

Binding dropdownlist with database table and get selected item n MVC

I am new to asp.net mvc.
I have a employee registration view, where i have a dropdown-list for for department, I want to bind the dropdown-list with a database table tblDepartment and i have did it. But I don't know how to get the select item of the list on post-back.
Employee Controller
[HttpGet]
public ActionResult AddEmployee()
{
ViewBag.Departments = new SelectList(_department.GetAll(), "id", "name");
return View(_employee.Get());
}
[HttpPost]
public ActionResult AddEmployee(FormCollection data)
{
var emp = _employee.Get();
emp.name = data["name"];
emp.age = Convert.ToInt32(data["age"]);
emp.dept_id = Convert.ToInt32(data["dept_id"]); // return dept_id 0 always.
emp.city = data["city"];
_employee.Insert(emp);
return RedirectToAction("Index");
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.name, "Name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.age, "Age", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.age, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.age, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.dept_id, "Department", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Departments", "Select Department")
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.city, "City", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.city, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.city, "", 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>
}
You are defining your dropdownlist with name DropDownLists i.e. #Html.DropDownList("Departments" which will be the name of the drop-down list so it will be rendered like:
<select name="Departments">
</select>
and in form post the values are posted in key value pair and the key is the name of the input element.
But in post request you are finding the posted value in dept_id, you need to read from correct key in FormCollection which would be:
emp.dept_id = Convert.ToInt32(data["Departments"]);
Side Note:
You should be using strongly typed helpers to post values directly to model and let the model binder do the magic for you, instead of populating the model manually.
For that your helper method would be DropDownListFor :
#Html.DropDownListFor(x=>x.dept_id ,ViewBag.Departments as SelectList, "Select Department")
and in action method set the parameter to be mode object:
[HttpPost]
public ActionResult AddEmployee(Employee employee)
{
If(ModelState.IsValid)
{
_employee.Insert(employee);
return RedirectToAction("Index");
}
else
{
return View(employee);
}
}

Confused with difference in MVC 5 TextBoxFor, EditFor, and TextAreaFor?

I've been having problems getting formatting to work in my MVC 5 View. The View was scaffold as a TextAreaFor. I added DataFormatting for my property in my ViewModel but it doesn't actually format for me. From everything I have researched I'm formatting the ViewModel correctly but I haven't been able to figure out why the formatting isn't actually working.
So, I tried using #Html.EditFor. That seemed to make the date formatting work but it didn't to apply the Bootstrap "form-control" class. I then tried #Html.TextBoxFor and it responded like the #Html.TextAreaFor, no formatting but did apply the Bootstrap class.
I don't know which one to use and what else I need to do to get my View to not only format the date but to also apply the Bootstrap CSS.
Here is my ViewModel property.
[DisplayName("Call Date")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime? CallDate { get; set; }
This is the original TextAreaFor that the scaffolding created. No formatting but Bootstap CSS works.
<div class="form-group">
#Html.LabelFor(model => model.CallDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.CallDate, new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(model => model.CallDate, "", new { #class = "text-danger" })
</div>
</div>
This is the EditFor that formats the date but doesn't apply Bootstrap CSS.
<div class="form-group">
#Html.LabelFor(model => model.CallDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CallDate, new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(model => model.CallDate, "", new { #class = "text-danger" })
</div>
</div>
This is the TextBoxFor that responded like the TextAreaFor.
<div class="form-group">
#Html.LabelFor(model => model.CallDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CallDate, new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(model => model.CallDate, "", new { #class = "text-danger" })
</div>
</div>
To add html attributes using #Html.EditorFor() you must be using MVC-5.1+, and if you are, then the usage is
#Html.EditorFor(m => m.CallDate, new { htmlAttributes = new { #class="form-control datepicker" }})
If you not using MVC-5.1+, and you want to generate a textbox and also format the date value, then the usage is (where the 2nd parameter is the format string)
#Html.TextBoxFor(m => m.CallDate, "{0:d}", new { #class = "form-control datepicker" })
Note that #Html.TextAreaFor() generate a <textarea> element for multi-line text and would not be appropriate for a DateTime property.

Passing form input from view to controller

I'm working with a standard razor view with form data. I want to pass the input form data to my controller after pressing the submit button. My view looks like this:
#model CareSource.ReleaseAssistant.Models.Prime.Team
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create New Team</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Team</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Abbreviation, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Abbreviation, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Abbreviation, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreatedBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CreatedBy, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CreatedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CreatedOn, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CreatedOn, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CreatedOn, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ModifiedBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ModifiedBy, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ModifiedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ModifiedOn, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ModifiedOn, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ModifiedOn, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
The problem is that the information in the form is not being passed back to my controller to be handled by my action method. I'm trying create a new entry in my database using web api. My action method looks like this:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
if (ModelState.IsValid)
{
HttpEndPointContext httpEndPoint = new HttpEndPointContext()
{
AuthenticationMethod = HttpAuthenticationMethods.None,
Ssl = false,
HttpMethod = HttpMethod.Post,
//Path = "localhost:32173/api/team/",
QueryStrings = null,
};
IProcessResult result = HttpConnectionManager.Current.SendMessage(httpEndPoint);
var response = result.ResponseData.ToString();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Most of the code in this project was generated using Codesmith Generator and uses the MicroORM called PetaPoco.
Since your form is strongly typed to an instance of Team and you are using that to generate the input form fields, you can use Team object as the parameter of your HttpPost method.
HttpPost]
public ActionResult Create(Team model)
{
if (ModelState.IsValid)
{
//access model.Properties
}
return View(model);
}
Do use Team model as parameter remove formCollection and try
Please update your View with the given code :
#using (Html.BeginForm("Create", "YourControllerName", FormMethod.Post, new { id = "form" }))
{
//Copy your current code as it is here.
}

While saving an image in my MVC WebApp, ModelState.IsValid always shows false

During Create, i always get the ModelState.IsValid as false and dont save my image in the database
In my model, the field for saving images is
[Required]
public byte[] BookingImage { get; set; }
In my controller, I have the following code:
public ActionResult Create([Bind(Include = "BookingId,BookingName,BookingDescription,ProviderId,EmployeeId,StatusId,BookingDuration,BookingTime, BookingImage, BookingRequestAmount,BookingReserveDeadline")] Booking booking, HttpPostedFileBase BookingImageHidden)
{
using (var ms = new MemoryStream())
{
BookingImageHidden.InputStream.CopyTo(ms);
booking.BookingImage = ms.ToArray();
}
if (ModelState.IsValid)
{
db.Booking.Add(booking);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.EmployeeId = new SelectList(db.Employee, "EmployeeId", "EmployeeName", booking.EmployeeId);
ViewBag.ProviderId = new SelectList(db.Providers, "ProviderId", "ProviderName", booking.ProviderId);
ViewBag.StatusId = new SelectList(db.Status, "StatusId", "StatusName", booking.StatusId);
return View(booking);
}
In my View, this is the code around the Image:
#model Sword.Models.Booking
#using (Html.BeginForm("Create", "bookings", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Booking</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.BookingName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BookingName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BookingDescription, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingDescription, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BookingDescription, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProviderId, "ProviderId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProviderId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ProviderId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EmployeeId, "EmployeeId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("EmployeeId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.EmployeeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StatusId, "StatusId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("StatusId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.StatusId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BookingDuration, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingDuration, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BookingDuration, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BookingTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingTime, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BookingTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BookingImage, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingImage, new { htmlAttributes = new { #class = "form-control" } })
<input name="BookingImageHidden" type="file" />
#Html.ValidationMessageFor(model => model.BookingImage, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BookingRequestAmount, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingRequestAmount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BookingRequestAmount, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BookingReserveDeadline, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BookingReserveDeadline, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BookingReserveDeadline, "", 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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
In my model, the field for saving images is [Required] public byte[]
BookingImage { get; set; }
Why do you even have a property in your model for the image if you are going to manually be reading it.
So simply consider using view models with the proper types (please notice that I am bolding the word view model here):
public class BookingViewModel
{
[Required]
public HttpPostedFileBase BookingImage { get; set; }
... some other properties that you need populated from the client
}
and then in your controller action get rid of these hacks and use the view model:
public ActionResult Create(BookingViewModel bookingVm)
{
if (ModelState.IsValid)
{
// In the MapFromViewModel you will obviously only
// map the properties that you need to be populated
// in your domain model from the view model. That's where
// you should put the logic of reading the image stream into a
// byte array which is what your domain model expects.
Booking booking = MapFromViewModel(bookingVm);
db.Booking.Add(booking);
db.SaveChanges();
return RedirectToAction("Index");
}
...
}
You got into all those troubles because you didn't use view models in the first place but rather you had your controller actions take your domain models as parameter which is one of the worst MVC design patterns I have ever seen in my life.

Resources