views:

356

answers:

1

I've written a class that contains Select- and Update-Methods for an ObjectDataSource. The UpdateMethod receives an instance of a called class. My problem is, that only properties that are Bound in the DetailsView are set, the others have their default value.

Here's my code:

Class declaration:

public class Foo
{
  public string Prop1 {get;set:}
  public int Prop2 {get;set;}
}

Updatemethod:

[DataObjectMethod(DataObjectMethodType.Update)]
public static void UpdateQuicklink(Foo item)
{
//  item.Prop1 // contains correct value
// item.Prop2 // is 0
}

Markup:

<asp:DetailsView ID="DetailsView1" runat="server" 
    DataSourceID="ods" EnableModelValidation="True" AutoGenerateInsertButton="True"
    AutoGenerateRows="False" AutoGenerateEditButton="True">
    <Fields>
        <asp:BoundField DataField="Prop1"/>
        <asp:BoundField DataField="Prop2" Visible="false"/>
    </Fields>
</asp:DetailsView>
<asp:ObjectDataSource ID="ods" runat="server"
    TypeName="NamespaceToClassContaingUpdateMethod"
    OldValuesParameterFormatString="original_{0}" 
    DataObjectTypeName="NamespaceToFoo" 
    UpdateMethod="UpdateQuicklink">
</asp:ObjectDataSource>

I can't expose every field I need to the markup.
A possible solution would be to rewrite my UpdateMethod to accept all necessary parameters, like that:

[DataObjectMethod(DataObjectMethodType.Update)]
public static void UpdateQuicklink(string Prop1, int Prop2)
{

}

But this solution is crap, due to I it is not flexible enough, if I attempt changes to the underlying datastructure. I know that in that case I'd have to edit my code nevertheless, but I'd to only have my custom wrapper class as parameter. Is that possible?

+2  A: 

It seems that the values of invisible DataControlFields (like BoundField) are not included in the ViewState and therefore not preserved during a roundtrip. Here is a discussion about the issue. Microsofts recommendation here is to add the field name for invisible fields to the DataKeyNames property of the data-bound control. You can remove then the invisible field from the Fields collection:

<asp:DetailsView ID="DetailsView1" runat="server" 
    DataSourceID="ods" EnableModelValidation="True" AutoGenerateInsertButton="True"
    AutoGenerateRows="False" AutoGenerateEditButton="True"
    DataKeyNames="Prop2">
    <Fields>
        <asp:BoundField DataField="Prop1"/>
    </Fields>
</asp:DetailsView>

That's not necessary for Controls in a Template - like a TextBox in an EditItemTemplate of a FormView which is bound using Text='<%# Bind("Prop2") %>'. Here ViewState is preserved during roundtrips even for an invisible TextBox (unless you disable ViewState of course).

Slauma
Thanks, exactly the kind of awswer I was looking for ;)
citronas
Haha, and it was even a luck for myself that I had looked for a solution to your question. Because today I had a very similar issue with an EntityDataSource and a field in a FormView which wasn't declaratively bound (only assigned in code-behind). Similar problem with updating the value. Then I remembered... "wasn't there this question?" ...and I've tried this "DataKeyNames" trick with that field and voila... it works! (I feel this really to be a weird "trick" or misuse of the property - recommended by MS or not - because my field has nothing to do with a "key".)
Slauma