【蛙蛙推荐】GridView和ObjectDataSource更新数据的一个Bug

相信大家在利用ObjectDataSource更新GridView或者FormView数据的时候一定遇到过这样的错误。
ObjectDataSource 'ods1' could not find a non-generic method 'ModifyPhrase' that has parameters: PID, pgid, content, Context.

你可以用google搜索一下这个错误,国内国外都有讨论,有人说这是微软的一个Bug。其实是因为GridView自动给数据源更新方法生成的参数不正确引起的。GridView在Updating事件里传递给DataSource的参数有DataKeyNames字段,以及你编辑状态下非readonly的字段,如果这几个字段加起来和数据源声明的几个参数对应起来,那么就会成功的调用数据源的更新方法,否则就会出现类似上面的错误。解决这个问题就是在Updating事件里处理传过去的参数。我做了一个例子。
这是数据源的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;

public class Entity
{
    
public Entity(int id, string name)
    
{
        m_id 
= id;
        m_name 
= name;
    }

    
int m_id;

    
public int Id
    
{
        
get return m_id; }
        
set { m_id = value; }
    }

    
string m_name;

    
public string Name
    
{
        
get return m_name; }
        
set { m_name = value; }
    }

}


[DataObject]
public class BLL
{
    
static Dictionary<intstring> dict = new Dictionary<intstring>();

    
public BLL()
    
{
     
    }


    [DataObjectMethod(DataObjectMethodType.Insert, 
true)]
    
public void Add(int id, string name)
    
{
        dict.Add(id, name);
    }


    [DataObjectMethod(DataObjectMethodType.Select, 
true)]
    
public Entity[] GetAll() 
    
{
        Entity[] entities 
= new Entity[dict.Count];
        
int i = 0;
        
foreach (KeyValuePair<intstring> kvp in dict)
        
{
            entities[i] 
= new Entity(kvp.Key, kvp.Value);
            i
++;
        }

        
return entities;
    }


    [DataObjectMethod(DataObjectMethodType.Update, 
true)]
    
public void Update(int pid, string pname)
    
{
        dict[pid] 
= pname;
    }


    [DataObjectMethod(DataObjectMethodType.Delete, 
true)]
    
public void Delete(int id) 
    
{
        dict.Remove(id);
    }

}

 

这是页面的代码

<%@ Page Language="C#" Debug="true" Trace="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected 
void LinkButton1_Click(object sender, EventArgs e)
    
{
        
int id;
        
int.TryParse(txtID.Text, out id);
        
new BLL().Add(id, txtName.Text);
        GridView1.DataBind();
    }

    protected 
void ObjectDataSource1_Updating(object sender, ObjectDataSourceMethodEventArgs e)
    
{
        
//update方法本来有俩参数pid和name,而key是id,而修改的数据是datafeild是name
        //所以我们要转换一下,并把不用的参数去调,另外参数不区分大小写
        e.InputParameters["pid"= e.InputParameters["Id"];
        e.InputParameters[
"pname"= e.InputParameters["name"];
        e.InputParameters.Remove(
"id");
        e.InputParameters.Remove(
"name");
    }

</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>测试GridView的编辑功能</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<!--要想使用GridView的编辑功能,要设置DataKeyNames属性,并把主键字段设置成ReadOnly
         字段声明这里一定要包含update方法需要的参数,然后在数据源的Updating事件里进行转换
         否则有些参数无法赋值了
         
-->
        
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" DataSourceID="ObjectDataSource1" DataKeyNames="ID" AutoGenerateColumns="False">
            
<Columns>
                
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
                
<asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True" />
                
<asp:BoundField DataField="Name" HeaderText="Name" />
            
</Columns>
            
<EmptyDataTemplate>
                没有数据
            
</EmptyDataTemplate>
        
</asp:GridView>
        
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="Delete"
            InsertMethod
="Add" SelectMethod="GetAll"
            TypeName
="BLL" UpdateMethod="Update" OnUpdating="ObjectDataSource1_Updating" >
            
<DeleteParameters>
                
<asp:Parameter Name="id" Type="Int32" />
            
</DeleteParameters>
            
<UpdateParameters>
                
<asp:Parameter Name="pid" Type="Int32" />
                
<asp:Parameter Name="pname" Type="String" />
            
</UpdateParameters>
            
<InsertParameters>
                
<asp:Parameter Name="id" Type="Int32" />
                
<asp:Parameter Name="name" Type="String" />
            
</InsertParameters>
        
</asp:ObjectDataSource>
        
<br />
        ID
<asp:TextBox ID="txtID" runat="server"></asp:TextBox><br />
        NAME
<asp:TextBox ID="txtName" runat="server"></asp:TextBox><br />
        
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">添加</asp:LinkButton></div>
    
</form>
</body>
</html>
posted @ 2006-10-18 08:36  蛙蛙王子  Views(3961)  Comments(5Edit  收藏  举报