Update database from viewmodel but add new records too - asp.net

I have a view that has a list of items (which can be added to dynamically via jQuery).
When I POST the viewmodel back to the controller, if the code can't find the ID, how do I insert new items and save them to the database.
My initial code is below - the updates are saved, but the new items aren't saved:
//
// POST: /Objective/Edit/model
[HttpPost]
public ActionResult Edit(ObjectivesEdit model)
{
if (model.Objectives != null)
{
foreach (var item in model.Objectives)
{
// find the database row
Objective objective = db.objectives.Find(item.ID);
if (objective != null)
{
// Set the database row to the posted values
objective.objective = item.objective;
objective.score = item.score;
objective.possscore = item.possscore;
}
else // database item not found, so add a new item
{
// add a new objective
// This doesn't seem to add/save a new record
Objective obj = new Objective();
obj.objective = item.objective;
obj.score = item.score;
obj.possscore = item.possscore;
}
}
// Save the changes to the database
db.SaveChanges();
}
return View(model);
}
Thanks for any help,
Mark

You don't add the newly created objective to your context.
else // database item not found, so add a new item
{
// add a new objective
// This doesn't seem to add/save a new record
Objective obj = new Objective();
obj.objective = item.objective;
obj.score = item.score;
obj.possscore = item.possscore;
// Missing line.
db.objectives.Add(obj);
}
if you're using EF 4.0 (i.e. db is of type ObjectContext), you should use the db.AddObject(obj).
Update based on your comment:
One way is to retrieve all added items after saving changes. Another way is to modify your model when creating a new objective. Changed parts are marked with *:
foreach (var item in model.Objectives.ToList()) // *:Notice the ToList()
{
// find the database row
Objective objective = db.objectives.Find(item.ID);
if (objective != null)
{
// Set the database row to the posted values
objective.objective = item.objective;
objective.score = item.score;
objective.possscore = item.possscore;
}
else // database item not found, so add a new item
{
// add a new objective
// This doesn't seem to add/save a new record
Objective obj = new Objective();
obj.objective = item.objective;
obj.score = item.score;
obj.possscore = item.possscore;
db.AddObject(obj)
// Save the changes to the database
db.SaveChanges(); // *: save in loop to get thee ID.
item.ID = obj.ID; // *: assign the ID to the model.
}
}
return View(model);

Related

How can I get item Ids without querying entire items?

I am trying to get a list of item ids with the code below, not a list of items, but I am not getting any Ids although the response message has Count set to the expected number of items. Could you please let me know if it is possible to get item ids only without item contents and how? Thanks.
string query = "select r.Id from root r where r.itemType = #itemType";
QueryDefinition queryDefinition = new QueryDefinition(query);
queryDefinition.WithParameter("#itemType", ItemType.Banana);
using (var feedIterator = container.GetItemQueryStreamIterator(queryDefinition))
{
while (feedIterator.HasMoreResults)
{
using (ResponseMessage responseMessage = await feedIterator.ReadNextAsync())
{
using (StreamReader streamReader = new StreamReader(responseMessage.Content))
{
using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
{
JsonSerializer jsonSerializer = new JsonSerializer();
JObject content = jsonSerializer.Deserialize<JObject>(jsonTextReader);
if (content.ContainsKey("Documents"))
{
foreach (var doc in content["Documents"])
{
// why doc is empty?
}
}
}
}
}
}
}
To just get the ids back without each one being it's own document, change your query to select value(r.Id) from root r where r.itemType = #itemType

View not update after POST although View Model updated

I am writing ASP.NET Custom Component, I want to update my view with following code below:
#if (Model.TableDatasource != null){
//Write some thing to html page example: tables or span
}
At the first, Model.TableDatasource is null, user choose information and Controller Review View(Model) like this:
var model = new PrintDeliveryTicketModel()
{
PlantList = CommonHelper.GetPlantList(),
};
if (request == null)
{
return View(model);
}
else
{
var currentPlant = JsonConvert.DeserializeObject<PlantList>(request);
var FullModel = new PrintDeliveryTicketModel()
{
PlantList = CommonHelper.GetPlantList(),
CurrentPlant = JsonConvert.DeserializeObject<PlantList>(request),
DriverList = JsonConvert.DeserializeObject<List<Drivers>>(CommonHelper.GetDriver(currentPlant.CodePlant, currentPlant.PlantNo.Value).Content.ReadAsStringAsync().Result),
CustomerList = JsonConvert.DeserializeObject<List<Customer>>(CommonHelper.GetCustomer().Content.ReadAsStringAsync().Result),
RecipeList = JsonConvert.DeserializeObject<List<Recipe>>(CommonHelper.GetRecipe(currentPlant.CodePlant, currentPlant.PlantNo.Value).Content.ReadAsStringAsync().Result),
SitesList = JsonConvert.DeserializeObject<List<Site>>(CommonHelper.GetSite().Content.ReadAsStringAsync().Result),
// TruckList = JsonConvert.DeserializeObject<List<Truck>>(CommonHelper.GetTruck().Content.ReadAsStringAsync().Result)
};
return View(FullModel);
}
At the Debug time, I notice that break-point stop at return View(FullMode) and Break-point at ViewFile(cshtml) has value. but nothing printed at view.
Hope some help.

If statement in Controller not saving changes

I have an if statement in my Controller which decides whether a checkbox is checked or not.
It works fine in the if statement and changes the properties, but when i go to send it back to the view these changes aren't saved.
Controller
public ActionResult GetUserRights(string userLogin)
{
if (userLogin != null)
{
Manager manager = new Manager();
var userlogin = manager.GetUserData(userLogin);
var userrights = userlogin.RightsId.Select(s => new { id = s, text = s });
var rightdetails = manager.GetAllRightsRows();
var rightsDetails = from r in rightdetails
orderby r.Id
select new RightDetail
{
RightID = r.Id,
RightDescription = r.Description,
RightName = r.Name,
ParentID = r.ParentId,
TypeColor = r.TypeColor,
Value = r.Value,
Checked = false
};
foreach (var userright in userrights)
{
foreach (var rightdets in rightsDetails)
{
if(rightdets.RightID == userright.id)
{
rightdets.Checked = true;
break;
}
}
}
return View("_RightsTreeListPartial", rightsDetails); <==== ALL CHECKED
PROPERTIES ARE false EVEN THOUGH SOME ARE BEING CHANGED IN THE IF STATEMENT.
}
return View("Index");
}
Let me know if you need any more info.
Thanks
With an IEnumerable, I am not sure of the reason why, but you cannot edit an item using an if statement so the code below is correct and does what it is supposed to, however as it is IEnumerable non of the changes are saved, also the process below is very heavy and long winded for what we need to do.
Original Code
foreach (var userright in userrights)
{
foreach (var rightdets in rightsDetails)
{
if(rightdets.RightID == userright.id)
{
rightdets.Checked = true;
break;
}
}
}
The new code takes a lot less time and will therefore improve the wait time. Firstly the IEnumerable is converted to a List, then, using a for-loop, the data is iterated through until a match is found, then within an if statement the item is changed (using original code and just converting from IEnumerable to List should work but I wouldn't recommend using it).
New Code
var rightdetail = rightsDetails.ToList();
foreach (var userright in userrights)
{
for (var i = 0; i < rightdetail.Count(); i++)
{
if (rightdetail[i].RightID == userright.id)
{
rightdetail[i].Checked = true;
break;
}
}
}

How do I add multiple rows to a sql server table based on multiple checkbox selections?

I have two tables: ServiceType and ServiceTerm.
The tables go hand in hand with one another, and get combined into the associative table ServiceRate. One ServiceType can have multiple ServiceTerms, but not always all of them.
On my asp.net form (VB) I want to code it to where there's a way for me to add each line to the database using a checkbox to select the ServiceTerms that apply to the selected ServiceType.
I'm completely new to asp.net, and pretty new to SQL Server 2008, too.
Here is an example I have done in one of my projects :
where chSportsList is Id for checkbox list
List<ListItem> list_chSportsList = new List<ListItem>();
foreach (ListItem chsli in chSportsList.Items)
{
Guid gui2 = Guid.Parse("00000000-0000-0000-0000-000000000000");
try
{
gui2 = Guid.Parse(chsli.Value.ToString());
}
catch { Response.Redirect("default.aspx"); }
db = new IRANSportEntities();
Customer_Sports customer_Sport = new Customer_Sports();
customer_Sport = db.Customer_Sports.FirstOrDefault(x => x.Id_Customer == gui1 && x.Id_Sports == gui2);
if (customer_Sport == null)
{
if (chsli.Selected == true)
{
db = new IRANSportEntities();
Customer_Sports _save = new Customer_Sports() { Id = Guid.NewGuid(), Id_Customer = gui1, Id_Sports = gui2 };
db.Customer_Sports.AddObject(_save);
db.SaveChanges();
}
}
else
{
if (chsli.Selected == false)
{
db.Customer_Sports.DeleteObject(customer_Sport);
db.SaveChanges();
}
}
}

Returning Arraylist from recursive function for ASP.Net

Please refer the attached screenshot. I have an array of the checkbox and a button for the post back in ASP.Net page. I have written a function as follows to determine what all check boxes have been checked on the button click event: The following code is a part of the business component which is called from ASP.Net. Please let me know how can I return actionArray back to calling functon in ASP.Net page.
public void checkBoxValidation(Control parent, string strKey)
{
XmlDocument getCyleXML = new XmlDocument();
string strChkID="", strActionXPath = "",strAction="";
ArrayList actionArray = new ArrayList();
// Loop through all the controls on the page
foreach (Control c in parent.Controls)
{
// Check and see if it's a checkbox.
if ((c.GetType() == typeof(CheckBox)))
{
// Since its a checkbox, see if this is checked.
if (((CheckBox)(c)).Checked == true)
{
// Find the ID of the checkbox
strChkID = ((CheckBox)(c)).ID.ToString();
getCyleXML = CycleXML(strKey);
strActionXPath = "/Actions/Action[checkbox='" + strChkID + "']/*[self::Name]";
strAction = getCyleXML.SelectSingleNode(strActionXPath).ToString();
actionArray.Add(strAction);
}
}
// Now we need to call itself (recursion) because all items (Panel, GroupBox, etc) is a container so we need to check
// all containers for any checkboxes.
if (c.HasControls())
{
checkBoxValidation(c, strKey);
}
}
}
The code should be like this :
public ArrayList checkBoxValidation(Control parent, string strKey, ArrayList actionArray)
{
XmlDocument getCyleXML = new XmlDocument();
string strChkID="", strActionXPath = "",strAction="";
if(actionArray == null) { actionArray = new ArrayList(); }
// Loop through all the controls on the page
foreach (Control c in parent.Controls)
{
// Check and see if it's a checkbox.
if ((c.GetType() == typeof(CheckBox)))
{
// Since its a checkbox, see if this is checked.
if (((CheckBox)(c)).Checked == true)
{
// Find the ID of the checkbox
strChkID = ((CheckBox)(c)).ID.ToString();
getCyleXML = CycleXML(strKey);
strActionXPath = "/Actions/Action[checkbox='" + strChkID + "']/*self::Name]";
strAction = getCyleXML.SelectSingleNode(strActionXPath).ToString();
actionArray.Add(strAction);
}
}
// Now we need to call itself (recursion) because all items (Panel, GroupBox, etc) is a container so we need to check
// all containers for any checkboxes.
if (c.HasControls())
{
checkBoxValidation(c, strKey, actionArray);
}
}
return actionArray;
}

Resources