为什么ObjectDataSource中的UpdateMethod只接收DetailsView中可见控件的属性值?

时间:2010-03-26 15:09:04

标签: c# asp.net objectdatasource detailsview

我编写了一个包含ObjectDataSource的Select和Update-Methods的类。 UpdateMethod接收被调用类的实例。我的问题是,只有在DetailsView中绑定的属性才被设置,其他属性都有默认值。

这是我的代码:

班级声明

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
}

标记

<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>

我无法将标记所需的每个字段暴露出来 一个可能的解决方案是重写我的UpdateMethod以接受所有必要的参数,如:

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

}

但是这个解决方案是垃圾,因为我不够灵活,如果我尝试更改底层数据结构。我知道在那种情况下我不得不编辑我的代码,但我只能将自定义包装类作为参数。这可能吗?

1 个答案:

答案 0 :(得分:4)

似乎隐形DataControlFields(如BoundField)的值未包含在ViewState中,因此在往返过程中不会保留。 Here是关于这个问题的讨论。微软建议here是将不可见字段的字段名称添加到数据绑定控件的DataKeyNames属性中。您可以从Fields集合中删除不可见字段:

<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>

对于模板中的控件而言,这不是必需的 - 就像使用Text='<%# Bind("Prop2") %>'绑定的FormView的EditItemTemplate中的TextBox一样。在这里,即使对于不可见的TextBox,也会在往返过程中保留ViewState(除非您当然禁用ViewState)。