如何在中继器 ASP.NET 内使用中继器

how to use repeater inside repeater ASP.NET

提问人:user15389524 提问时间:8/1/2021 最后编辑:user15389524 更新时间:8/3/2021 访问量:491

问:

我在数据库中有两个表(客户和订单),每个客户都有一个订单列表。我在 ASP.NET 中制作了 HTML JavaScript 和 CSS 代码来显示它们,如图所示,我在另一个中继器中使用中继器来显示客户及其订单,但我有 NullReferenceException,我不知道为什么看不到表中的行。

我的数据库

ASP 代码

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="test10.WebForm2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<br />
<br />
<br />
<div class="container">
    <div class="bs-example">
        <div class="accordion" id="accordionExample">

            <asp:Repeater ID="rptCustomers" runat="server" OnItemDataBound="OnItemDataBound">
                <ItemTemplate>
                    <div class="card">
                        <div class="card-header folded-corner"  id="9y">
                            <button type="button" class="btn btn-link"  data-toggle="collapse" data-target="#8y">
                                <i class="fa fa-plus pr-5 iconstyle"></i>
                                <span class="pl labilstyle" >
                                    <%#  Eval("ContactName")   %> 
                                </span>
                            </button>
                            <asp:HiddenField ID="hfCustomerId" runat="server" Value='<%# Eval("CustomerId") %>' />
                        </div>
                        <div id="8y" class="collapse" aria-labelledby="9y" data-parent="#accordionExample">

                            <asp:Panel ID="pnlOrders" runat="server" Style="display: none">
                                <asp:Repeater ID="Repeater8" runat="server" EnableViewState="true">

                                    <ItemTemplate>
                                        <div class="">
                                            <div class="col-md-2 pt-3 mb-3 pr-4 mr-5 mt-3 text-center x " style="border-radius: 20px;border:1px solid rgba(0,0,0,.125); overflow:hidden; align-items: stretch!important;box-shadow: 0 6px 9px 0 rgb(0 0 0 / 9%); ">
                   
                                                <div class=" text-center">
                                                    <asp:Label ID="lblOrderId" runat="server" Text='<%# Eval("OrderId") %>' />
                                                </div>
                                                <hr />  
                                            </div>
                                        </div>
                                    </ItemTemplate>
                                </asp:Repeater>
                            </asp:Panel>
                        </div>
                    </div>
                </ItemTemplate>
            </asp:Repeater>
        </div>
    </div>
</div>

<script>
    $(document).ready(function () {
        // Add minus icon for collapse element which is open by default
        $(".collapse.show").each(function () {
            $(this).prev(".card-header").find(".fa").addClass("fa-minus").removeClass("fa-plus");
        });

        // Toggle plus minus icon on show hide of collapse element
        $(".collapse").on('show.bs.collapse', function () {
            $(this).prev(".card-header").find(".fa").removeClass("fa-plus").addClass("fa-minus");
        }).on('hide.bs.collapse', function () {
            $(this).prev(".card-header").find(".fa").removeClass("fa-minus").addClass("fa-plus");
        });
    });
</script>

</asp:Content>

这是 C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;


namespace test10
{
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                rptCustomers.DataSource = GetData("SELECT TOP 2 * FROM Customers");
                rptCustomers.DataBind();
            }
        }

        private static DataTable GetData(string query)
        {
            string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
            using (SqlConnection con = new SqlConnection(constr))
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    cmd.CommandText = query;
                    using (SqlDataAdapter sda = new SqlDataAdapter())
                    {
                        cmd.Connection = con;
                        sda.SelectCommand = cmd;
                        using (DataSet ds = new DataSet())
                        {
                            DataTable dt = new DataTable();
                            sda.Fill(dt);
                            return dt;
                        }
                    }
                }
            }
        }

        protected void OnItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                string customerId = (e.Item.FindControl("hfCustomerId") as HiddenField).Value;
                Repeater rptOrders = e.Item.FindControl("rptOrders") as Repeater;
                rptOrders.DataSource = GetData(string.Format("SELECT TOP 1 * FROM Orders WHERE CustomerId='{0}'", customerId));
                rptOrders.DataBind();
            }
        }
    }
}

更新:如何在查询中调用列表 我的代码:

List<int> PubsID = new List<int>();
            PubsID = User_Profile.Instance.GetPublisherIDForCurrentUser(UniID);  


            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                string customerId = (e.Item.FindControl("hfCustomerId") as HiddenField).Value;
                Repeater rptOrders = e.Item.FindControl("rptOrders") as Repeater;
                string constr = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;
                using (SqlCommand cmdSQL = new SqlCommand("SELECT * FROM [b] where KindID=1 and Active=1 and Type = @CID and id in (@id)",
                            new SqlConnection(constr)))
                {
                    cmdSQL.Connection.Open();
                    cmdSQL.Parameters.Add("@CID", SqlDbType.Int).Value = customerId;
                    cmdSQL.Parameters.Add("@id", PubsID);
                    rptOrders.DataSource = cmdSQL.ExecuteReader();
                    rptOrders.DataBind();
                }

JavaScript C# asp.net repeater NullReferenceException

评论

0赞 Filburt 8/1/2021
这回答了你的问题吗?什么是 NullReferenceException,如何修复它?
1赞 Greg 8/1/2021
rptOrders在 HTML 上不存在。也许你的意思是Repeater8
0赞 Albert D. Kallal 8/1/2021
看起来您在 cusotmerID 周围有 ' - 您确定数据库中的数据类型是字符串吗?如果没有,则删除单引号。这就是为什么我更喜欢 vb.net 的原因——自动投射更频繁地让你不必联系 SO——我一遍又一遍地看到这一点。
0赞 mason 8/1/2021
@AlbertD.Kallal 与其担心引号,不如直接跳到正确的解决方案:一个参数化的查询来防止 SQL 注入攻击?
0赞 mason 8/1/2021
您的代码容易受到 SQL 注入攻击 - 您应该阅读有关 Bobby Tables 以及如何修复它的信息。不要通过串联字符串形成 SQL 查询。

答:

0赞 Albert D. Kallal 8/2/2021 #1

看起来您在查询值周围有引号 -

更好的是,为什么不使用参数。他们有两个原因

一、更安全——不易发生sql注入

第二,为字符串和数字添加额外的引号是自动完成的 - 因此它适用于两种情况(字符串或数字)。

所以,我建议这段代码:

   protected void OnItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            int customerId = Int32.Parse(e.Item.FindControl("hfCustomerId") as HiddenField).Value);
            Repeater rptOrders = e.Item.FindControl("rptOrders") as Repeater;
            string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;

        using (SqlCommand cmdSQL = new SqlCommand("SELECT TOP 1 * FROM Orders WHERE CustomerId = @CID",
            new SqlConnection(constr)))
        {
            cmdSQL.Connection.Open();
            cmdSQL.Parameters.Add("@CID", SqlDbType.Int).Value = customerID;
            rptOrders.DataSource = cmdSQL.ExecuteReader();
            rptOrders.DataBind();
        }
   }

因此,以上消除了此处的单个'(引用)问题。

评论

0赞 user15389524 8/3/2021
是的,你能帮我了解如何调用list<int>在更新中查询我的代码吗?
0赞 Albert D. Kallal 8/3/2021
Type 是 SQL 中的保留字 try [Type] = bla bla bla