在Asp.net中通过命令参数(CommandArgument)传递多个参数

34

我有一个包含多行的网格视图,每一行都有一个更新按钮,当某个人点击更新按钮时,我需要传递2个值。 除了将参数打包在CommandArgument中并用逗号分隔(过时且不优雅)之外,我如何传递超过一个参数?

<asp:LinkButton ID="UpdateButton" runat="server" CommandName="UpdateRow" CommandArgument="arg_value" Text="Update and Insert" OnCommand="CommandButton_Click" ></asp:LinkButton>

需要说明的是,这些值无法从页面上的任何控件中检索,因此我目前不在寻求任何设计解决方案。


7
有时候,使用分隔符这个“古老的”解决方案是最简单的。 - Kelsey
@sarsnake - 我会接受Archana Motagi的答案。 - fubo
8个回答

83

你可以将分号分隔的值作为命令参数传递,然后拆分字符串并使用它。

<asp:TemplateField ShowHeader="false">
    <ItemTemplate>
       <asp:LinkButton ID="lnkCustomize" Text="Customize"  CommandName="Customize"  CommandArgument='<%#Eval("IdTemplate") + ";" +Eval("EntityId")%>'  runat="server"> 
       </asp:LinkButton>   
    </ItemTemplate>   
</asp:TemplateField>

在服务器端

protected void gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
      string[] arg = new string[2];
      arg = e.CommandArgument.ToString().Split(';');
      Session["IdTemplate"] = arg[0];
      Session["IdEntity"] = arg[1];
      Response.Redirect("Samplepage.aspx");
}

以上对我有效。唯一的问题是您在Redirect() ASPX链接中缺少参数。请尝试使用以下代码:Response.Redirect("Samplepage.aspx?IdTemplate=" + Session["IdTemplate"].ToString().Trim() + "&IdEntity=" + Session["IdEntity"].ToString().Trim()); - Fandango68
作为一个吹毛求疵的人,你不需要使用.ToString()。CommandArgument总是一个字符串,所以代码如下:var argument = ((LinkButton)sender).CommandArgument.Split(';'); - Norbert Norbertson

17

@Patrick的答案很好,值得更多的赞扬!您可以拥有任意数量的数据项,它们都是独立的,如果需要,可以在客户端使用。

它们也可以在代码中声明而不是在代码中添加。我刚刚为类似于以下方式的 GridView 添加了这个:

<asp:TemplateField HeaderText="Remind">
  <ItemTemplate>
    <asp:ImageButton ID="btnEmail"  
        data-rider-name="<%# ((Result)((GridViewRow) Container).DataItem).Rider %>"
        data-rider-email="<%# ((Result)((GridViewRow) Container).DataItem).RiderEmail %>"
        CommandName="Email" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/images/email.gif" />
  </ItemTemplate> 
</asp:TemplateField>

在 RowCommand 中,你需要这样做:

void gvMyView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "Email")
    {
        var btnSender = (ImageButton)e.CommandSource;
        var riderName = btnSender.Attributes["data-rider-name"];
        var riderEmail = btnSender.Attributes["data-rider-email"];
        // Do something here
    }
}

使用分隔符将所有值混在一起,然后在最后解包比起这种方法来说要麻烦得多,这种方法更加简洁明了。

别忘记测试和清理从页面获取回来的任何数据,以防它被篡改!


2
我喜欢这种方法,它能够尽可能地实现强类型化的项,使用逗号和子字符串来分离这种信息虽然可行,但会变得混乱。你需要内在地了解每个参数的含义,使用"data-"容器更加安全,可以使代码更易读。 - GJKH

16

在查看了一些资料后,发现Kelsey是正确的。

只需使用逗号或其他分隔符,在需要消费它时进行拆分即可。


5
发现这个链接: http://aspdotnetcodebook.blogspot.com/2008/09/how-to-pass-multiple-values-to.html - sarsnake

9

我的方法是使用属性集合从后台代码中添加HTML数据属性。这更符合jQuery和客户端脚本的要求。

// This would likely be done with findControl in your grid OnItemCreated handler
LinkButton targetBtn = new LinkButton();


// Add attributes
targetBtn.Attributes.Add("data-{your data name here}", value.ToString() );
targetBtn.Attributes.Add("data-{your data name 2 here}", value2.ToString() );

然后通过属性集合检索值。
string val = targetBtn.Attributes["data-{your data name here}"].ToString();

4
以下是翻译的结果:

一种更加优雅的方法是在上述评论的基础上添加..

<asp:GridView ID="grdParent" runat="server" BackColor="White" BorderColor="#DEDFDE"
                           AutoGenerateColumns="false"
                            OnRowDeleting="deleteRow"
                         GridLines="Vertical">
      <asp:BoundField DataField="IdTemplate" HeaderText="IdTemplate" />
      <asp:BoundField DataField="EntityId" HeaderText="EntityId"  />
    <asp:TemplateField ShowHeader="false">
        <ItemTemplate>
           <asp:LinkButton ID="lnkCustomize" Text="Delete"  CommandName="Delete"  CommandArgument='<%#Eval("IdTemplate") + ";" +Eval("EntityId")%>'  runat="server"> 
           </asp:LinkButton>   
        </ItemTemplate>   
    </asp:TemplateField>
     </asp:GridView>

在服务器端:

protected void deleteRow(object sender, GridViewDeleteEventArgs e)
{
    string IdTemplate= e.Values["IdTemplate"].ToString();
    string EntityId = e.Values["EntityId"].ToString();

   // Do stuff..
}

1
只有在您希望在网格中显示IdTemplate和EntityId字段时,此方法才有效。您放置在CommandArgument中的值实际上从未被使用过。 - cyberspy

2

要存储两个值,只有三种方法:将它们存储在gridview数据键集合中、将它们存储在同一单元格内的隐藏字段中或将这些值连接在一起。无法在一个链接中存储两个值。


0
如果您想传递两个值,可以使用以下方法。
<asp:LinkButton ID="RemoveFroRole" Text="Remove From Role" runat="server"
CommandName='<%# Eval("UserName") %>' CommandArgument='<%# Eval("RoleName") %>'
 OnClick="RemoveFromRole_Click" />

基本上我将{CommmandName,CommandArgument}视为键值。从数据库字段设置两者。在这种情况下,您将需要使用OnClick事件并使用OnCommand事件,我认为这是更清晰的代码。


0
你可以使用分隔符(不能在参数值内部 - 例如 "|") 来分割参数。 参数的名称必须是数据源的有效名称。 使用单引号表示命令参数,使用双引号表示参数的名称。
<%-- BUTTON VIEWCMD --%>
<asp:TemplateField HeaderText="" SortExpression="" ItemStyle-CssClass="widthP07 textAlignCenter">
    <ItemTemplate>
        <asp:Button ID="ButtonVIEWCMD" runat="server" Text="View Detail"
         CommandName="VIEWCMD" 
         CommandArgument='<%# Eval("param1") + "|" + Eval("param2") + "|" + Eval("param3") %>' />
                        
    </ItemTemplate>
</asp:TemplateField>

服务器代码
/// <summary>
/// SET - Process GridView Row Commands
/// </summary>
protected void GridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // INIT 
    string tempArguments = string.Empty;

    try
    {
        // CTRL - gridview row click
        switch (e.CommandName)
        {
            case "VIEWCMD":
                // GET 
                tempArguments = (string)(e.CommandArgument);
                // GET 
                string[] tempParam = tempArguments.Split('|');

                // GET 
                // tempParam[0];
                // tempParam[1];
                // tempParam[2];
                
                // .........

                break;

            default:
                break;
        }
    }
    catch (Exception ex)
    {
        // ERR .......
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接