Hi
I don't seem to be able to get the model binder to add and remove items from a child collection. Updates work, e.g.:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, FormCollection collection)
{
collection.Add("Resources[0].Role", "1"); // current value is 3. update works
collection.Add("Resources[1].Role", "2"); // need to add a new item for 2. nothing happens
var project = Project.GetProject(id);
if (TryUpdateModel(project) && SaveObject(project, true))
{
return RedirectToAction("Index");
}
ViewData.Model = project;
return View();
}
Shouldn't the model binder call list.Add and list.Remove depending on the contents of the current list and the keys and values in the MVC FormCollection?
Many thanks
Andrew
Maybe that should be list.AddNew() and list.RemoveAt(index). It looks like the DefaultModelBinder clears the list first which wouldn't work very well for CSLA I think.
What's the thinking behind BindCslaCollection? It only loops throught the existing collection so can't add new items.
Hmmm.
Which version of CSLA? 3.8 didn't have support for collections IIRC.
Heh, sorry I didn't see the 4.0 on the subject :) haven't used 4.0 yet so can't help, but reading down the thread, I do agree that it is something that would be nice to have (add/remove). I do a lot of removing / adding client side and currently handle that by going through the form collection and adding/removing.
I was considering adding add/remove collection during proof of concept (see http://cslacontrib.codeplex.com/SourceControl/changeset/view/74794#986703 BindCslaCollectionModel) but decided that at framework level is a little dangerous. Moreover, in MVC pattern is more natural to have Add and Remove action method and not combine these actions into one Edit action method.
Here is the test script describing what the model binder can currently do: http://www.lhotka.net/cslacvs/viewvc.cgi/core/trunk/Source/Csla.Web.Mvc.Test/ModelBinderTest/CslaModelBinderTest.cs?revision=4821&view=markup
HTH,
Ricky
Hi rasupit
I understand what you are saying about Add and Remove being separate actions. That does makes sense except when, like me. you are adding and removing items client-side. Also it means I must maintain the state of the object between page requests. That's not the end of the world.
The thing is that as the default model binder deals with add and removes it feels right to me that the Csla version should do the same. If you've already taken care of adding and removing in previous actions then it won't matter anyway. I don't think it's dangerous. You've got to build in enough validation to stop dodgy requests busting the object anyway.
That's just my opinion anyway.
Cheers
Andrew
You should be able to separate the action methods even when adding/removing items from client side. I have the example how you call an action method using jquery like the following: http://cslacontrib.codeplex.com/SourceControl/changeset/view/74794#986708
$("form", newpnl).submit(function(e) {
e.preventDefault();
$.post(this.action, $(this).serialize(),
function(result) {
if (result.Success) {
var item = $(tmplt).appendTo("#role-list");
$("h3", item).text(result.Data.Name);
$("input", item).val(result.Data.Id);
newpnl.dialog("close");
}
else {
alert(result.Messages);
}
}
);
});
$("a.delete").live("click", function() {
var item = $(this).parent("li");
$.post('<%=Url.Action("Delete", "Roles")%>', { id: $("input:hidden", item).val() },
function(result) {
if (result.Success) {
item.remove();
}
else {
alert(result.Messages);
}
}
);
});
The default model binder does deal with add and removes however,
you would've use this against your view-model and not against your model right?. ;).
I get it that my statement was pretty subjective here,
and you should be allowed to run with scissor, especially on asp.net MVC.
During the proof of concept I found is not easy to implement this for csla object.
What I was trying to say was that this features was on the list but not make past
my wish list to pursue after weighing in all these factors.
Thanks,
Ricky
Hi Ricky,
>> The default model binder does deal with add and removes however, <<
The problem we found with the default model binder is that it appears it removes all items from the collection and then re-adds new ones from the posted values. Which ofcourse then results in items in the deleted list and those get deleted and persisted again.
One more thing regarding client side add/remove. I am not sure if this is the OP case, but for me I add / remove items in the DOM. Nothing gets persisted until user "Saves". At that time we look at what is posted and update our models accordingly.
Hi
I agree with xAvailx, we need the option of adding and removing from the object one at a time or by a batch with one controller action. As we know it's not really acceptable to clear the Csla collection first which makes things more difficult. As a compromise I clear the list only when the count with the form values is not the same as the collection count. That way the collection doesn't get dirty if there are no changes.
I vote to keep it on the wish list in the hope that a solution gets into production soon.
Thanks
Andrew
The list I described was my personal list to I would like to pursue through proof of concept. As for wish list to be implemented on CSLA, this will be solely on Rocky's decision.
One challenge I would can see is to be able to instantiate csla object, because having to just call AddNew is not a complete solution unless overriding AddNewCore is a requirement in CSLA. However, it should be a good challenge to pull this off.
Ricky
I would think that calling AddNew would be fine. In CSLA 4 there's always a default implementation of AddNewCore that just uses DataPortal.CreateChild, so in general it should work.
I modified CslaModelBinder.cs to support doing it all at once. You need to use the Microsoft form element naming convention ie. Objectname[0].IsNew and include the IsNew, IsDeleted stuff. I'm not sure what all the repercussions are, so I'm putting it out there. see my code on this post:
what object type if your view bound to? Project? does the view object also contain the child collection or is that only in the controller?
Copyright (c) Marimer LLC