How To Not Have ALL Fields On An Edit View But Not Get The 'Overflow while converting to datetime.' - asp.net-mvc-3

I am somewhat new to MVC 3 so this could be something simple. I have a Compact SQL 4 database. There is a Post object that has a Contents (string), Subject (string), When (DateTime) and Reposted (DateTime nullable) fields. During the Create's Post method, I manually force the When property to be DateTime.Now and it works great.
However, on my Edit View, I do NOT want to show this field or at least not let it be an editable field. When I do NOT put it as an editable field on the Edit View and they change say the Contents and then click Save I get the message:
An overflow occurred while converting to datetime.
During the Edit Postback, I am setting the Reposted field to DateTime.Now so it has to be the When field. When I debug on that postback I see that the "Post" object is only filled in with values of the fields I am displaying on the screen. So I decided to just grab the When field out with a LINQ query directly from the data but when I get to the SaveChanges it fails and says the following:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key
So how can I update an object and let the user only change a few pertinant fields? Seems like the Post object is not getting ALL of the existing values since they are not showing on the screen. How can I fill that object completely?
Edit: Here is the Post method.
[HttpPost]
public ActionResult Edit(Post post) {
if (ModelState.IsValid) {
db.Posts.Attach(post);
int Successes = 0;
int Failures = 0;
this.SendEMail(post, out Successes, out Failures);
post.Successes = Successes;
post.Failures = Failures;
post.Reposted = DateTime.Now;
db.ObjectStateManager.ChangeObjectState(post, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(post);
}

Include a hidden field in your view for the fields that you do not want to display e.g.
#Html.HiddenFor(model => model.When)

Related

Why I am getting ModelState.IsValid = false?

I have a update controller action which is invoked when the form is posted.
In the form there is a radio button that controls the visibility of a drop down field
If drop down field is visible and I post the form, database is updated fine and ModelState is valid.
When the drop down field hidden and I post the form, it posts and updates the database.
But the ModelState.IsValid = false and the drop down is being reported as Missing value.
How to fix this issue?
[HttpPost]
public ActionResult Update(ResponseModel model)
{
//ModelState.IsValid = false when dropdown field hidden
//validate form fields
//update database
//if we are here, then db update successful
AjaxResponse.AddJsonItem("msg", "Success");
return Result();
}
It could be that your ResponseModel has a property annotated with some data annotation like [Required] and when you uncheck your radio box that property doesn't get a value.
Post your model and post the values you receive when state is invalid (By checking in debugger).
Since you only have one property and that is integer. Your model state is invalid because integer can not have null value. When you make it hidden the model doesn't have value for the int property. Either replace the dropdown with hidden field on radio box or make it a nullable int.

How can I put my fieldsets side-by-side?

would like to put fieldSets side-by-side on my “Edit” page because I have so many fields on the page. Since I couldn’t find an easy fix, I decided to put the fields in a table. This worked fine except for when I click on the “Save” button I get this error:
“Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.”
Questions: How can I put my fieldsets side-by-side or make my table to work with the save button?
Thanks for any help.
Here's the edit methods of my controller:
public ActionResult Edit(int id)
{
CourseProgress courseprogress = db.CourseProgresses.Find(id);
ViewBag.CourseId = new SelectList(db.Courses, "CourseId", "Name", courseprogress.CourseId);
ViewBag.TeacherId = new SelectList(db.Teachers, "TeacherId", "Name", courseprogress.TeacherId);
var PdfReportProperties = new PdfReport();
return View(courseprogress);
}
//
// POST: /ProgressManager/Edit/5
[HttpPost]
public ActionResult Edit(CourseProgress courseprogress)
{
if (ModelState.IsValid)
{
db.Entry(courseprogress).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("ProgressRecord");
}
ViewBag.CourseId = new SelectList(db.Courses, "CourseId", "Name", courseprogress.CourseId);
ViewBag.TeacherId = new SelectList(db.Teachers, "TeacherId", "Name", courseprogress.TeacherId);
return View(courseprogress);
}
The most likely reason you are getting that error is that as you don't have a field for the ID of your model in the form, once you hit the SAVE button, the object you are editting has its ID property in null.
To solve it, use a hidden field holding the ID of the model, so that once the form post its fields it became mapped in your controller model object.
This problem has nothing to do with the position or layout of your fields.

MVC ddl value after postback

I have a ddl which is populated with hours of day 01-23. This is on a form which is used to book an item of equipment. The hour is populated to a db field. The issue is this, when the booking form is opened to alter the time the ddl shows the hour that was booked, when changed though and the form is submitted the value passed on post is the initial value from db not the new selected hour.
this is the basic pieces of code. any idea why the newly selected ddl value is not passed to the model??
View
<%= Html.DropDownList("ddl_Hour", Model.ddlHour,
new { #class = "DropDown", style = "width: 40px” })%>
Model
private string _ddlHourSelectedValue = "0";
public SelectList ddlHour
{
get
{
return (new System.Web.Mvc.SelectList(_ddlHour, "intValue", "Text", Convert.ToInt32(_ddlHourSelectedValue)));
}
}
public string ddlHourSelectedValue
{
get
{
return _ddlHourSelectedValue;
}
set
{
_ddlHourSelectedValue = value;
}
}
param[6] = new SqlParameter("#Timeslot", ddlHourSelectedValue);
The field in your view is called "ddl_Hour" However is there a variable in your Model with the same name? Otherwise the MVC framework will not automatically populate the value in the model.
Two ways you could go about this.
1
In your controller methods that accepts a post, you can add the parameter: FormCollection fc to the method. This key value pair collection will allow you to fetch results from fields in the post data like so:
string selectedValue = fc["ddl_Hour"];
2
Or you can modify your model to include a variable with the same name as the drop down list so that it is automatically populated for you.
public string ddl_Hour { get; set; }
You should then be able to access the result of the drop down list selection on post from that variable.

MVC 3 Details View

I am new to MVC frame work. And i am making one page where we can see details of department by clicking on details link button.
While User click link button it fetch the all the records of the particular department in List Collection and redirect to Details View.Data has been fetched in List but while going to Details view it Generates following error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[DocPageSys.Models.Interfaces.DepartmentInfo]', but this dictionary requires a model item of type 'DocPageSys.Models.Interfaces.DepartmentInfo`'.
I understood the error but confusion to solve it.And stuck with this problem...
Since your Details view is strongly typed to DepartmentInfo:
#model DocPageSys.Models.Interfaces.DepartmentInfo
you need to pass a single instance of it from the controller action instead of a list:
public ActionResult Details(int id)
{
DepartmentInfo depInfo = db.Departments.FirstOrDefault(x => x.Id == id);
return View(depInfo);
}
So make sure that when you are calling the return View() method from your controller action you are passing a single DepartmentInfo instance that you have fetched from your data store.
To make it run fine initially you could simply hardcode some value in it:
public ActionResult Details(int id)
{
var depInfo = new DepartmentInfo
{
Id = 1,
Name = "Sales",
Manager = "John Smith"
}
return View(depInfo);
}
Oh, and you will notice that I didn't use any ViewData/ViewBag. You don't need it. Due to their weakly typed nature it makes things look really ugly. I would recommend you to always use view models.
Passing a list instead of a single item
This error tells you, that you're passing a list to your view but should be passing a single entity object instance.
If you did fetch a single item but is in a list you can easily just do:
return View(result[0]);
or a more robust code:
if (result != null && result.Count == 1)
{
return View(result[0]);
}
return RedirectToAction("Error", "Home");
This error will typically occur when there is a mismatch between the data that the controller action passes to the view and the type of data the view is expecting.
In this instance it looks as if you're passing a list of DepartmentInfo items when your view is expecting a single item.

jqGrid saving a row with nullable columns

So I have a jqGrid on an ASP.NET MVC 3 website. It's loading the data, searching, filtering, and saving rows with the built in pop-up editor. What I can't get to work is saving a nullable property. I'm using LargeJsonResult instead of the built in JsonResult, so an example of a row in the grid is this:
// C# class
public class Row
{
public string A { get; set; }
public string B { get; set; }
public int C { get; set; }
}
// an example object instance, let's say these values come from the DB
var ret = new Row { A = "a", B = null, C = 5 };
// the JSON string sent to the grid will look like this (notice B is omitted)
// "{ A: 'a', C: 5 }"
Now, the grid will show this as:
A B C
a undefined 5
And this brings me to my problem. The pop-up edit form will show "undefined" in the textbox for B, and will also post this to the server. So if I save that to the database, I'll have "undefined" in my DB instead of null.
How do I get jqGrid to preserve the null value round trip? One solution that seems to me very hacky is based on something Oleg solved in another thread:
// override jqGrid serialization
jQuery.extend(jQuery.jgrid.edit, { ajaxEditOptions: { contentType: "application/json" }, serializeEditData: function (data) {
return JSON.stringify(data).replace(/"undefined"/g, 'null');
}});
This will work, but seems dangerous because it's doing mass edits of data without the user's knowledge. In thinking more about it, I guess this is the fundamental problem of saving back null instead of "undefined" or some other string representation of null (empty string, etc.). The desired behavior would be:
if the property is null, and the user doesn't change the value, it posts as null
if the user changes the value, the property is no longer null
Can we get the grid's edit form to behave like this for nullable properties? Or would I have to create a custom edit form that tracks what the user does with a property?
I hope that I understand your problem. In one my applications where I used jqGrid I had once the problem with NULL values. At the time of development of the application I was not sure how to solve the problem and I placed on the server side the text value "(NULL)" instead of null value of one property. The grid was for advanced users who understand what "(NULL)" is. The value "(NULL)" has no sense in the field (one had no user account with the name) and inside of server code for the Edit operation I could distinguish "(NULL)" value from the real field value. In the way I could come over the problem.
In your case you should solve at least two problems:
You should decide how the null value should be displayed. The "undefined" text seems me not the best one. You can solve the problem with the "undefined" text either on the server side (like I did in my case) or with respect of custom formatter. The custom formatter is very simple thing. It define how a cell value should be displayed as a HTML fragment of the <td> contain. You can for example include an additional hidden <span> element or other HTML element or attribute which will save the information that the value was null.
You should solve the problem with decoding of the null value on the server side during Edit operations. You can solve the problem very easy on the server side (like I do with compare of the corresponding field to the "(NULL)") or with respect of custom unformatter on the client side. The custom unformatter will get the information from the grid cell (from the hidden <span> or other hidden HTML element or attribute) and place the information in the server request.
You can look at the demo for the answer to see an example how one can use a hidden <span> to save an additional information in the cell with respect of custom formatter and to read the information later with respect of custom unformatter.

Resources