简体   繁体   English

即使启用了runat = server,为什么也看不到HtmlTables上的任何数据?

[英]Why can't I see any data on HtmlTables even with runat=server enabled?

I have two HTML tables, the first one is populated on the server side through entries in the database, and the second is populated through client-side Javascript that allows the user to dynamically add rows and enter in data through input text boxes. 我有两个HTML表,第一个通过数据库中的条目填充在服务器端,第二个通过客户端Javascript填充,该Javascript允许用户动态添加行并通过输入文本框输入数据。

A button at the end of my form is responsible for committing the data from both to a SQL Server back end. 表单末尾的按钮负责将数据从这两者提交到SQL Server后端。 The issue is on postback I am not able to read from these tables. 问题是回发,我无法从这些表中读取。 This is the case for the client-side managed table, as well as the server sided managed table. 客户端托管表和服务器端托管表都是这种情况。

<table style="display: none; width: 100%" runat="server" id="tblWebOrderArbitraryContacts" class="borderBottomStyle">
                                            <table runat="server" id="recipientTable" style="display: block; width: 100%" class="borderBottomStyle"></table>



//the problem is the row count is always zero, regardless of what data is in it

if(tblWebOrderArbitraryContacts.Rows != null && tblWebOrderArbitraryContacts.Rows.Count > 0)
            {
                //go through automatically derived (from integrations) contacts
                foreach (HtmlTableRow row in tblWebOrderArbitraryContacts.Rows)
                {
...

Explanation 说明

The issue is that when a request is sent to the server for that page, a new instance of the page is created, along with all of the controls as defined within your .aspx file. 问题在于,当将请求发送到该页面的服务器时,将创建该页面的新实例,以及.aspx文件中定义的所有控件。 This new instance of the page and child controls start out with no data. 页面和子控件的这个新实例开始时没有数据。

When you submit a "post" request back to the server (a "Postback"), the page looks at the request's form collection (the data from <input> tags submitted by the browser) and attempts to update the web controls on the page with the data found within that form collection. 当您向服务器提交“发布”请求(“发布”)时,页面将查看请求的表单集合(浏览器提交的<input>标记中的数据),并尝试更新页面上的Web控件以及在该表单集合中找到的数据。

Also, but beside the point, viewstate aware controls may attempt to populate themselves based on data found in viewstate left behind by a different instance of the same control from a previous request. 同样,但要紧的是,了解视图状态的控件可能会尝试根据视图状态中发现的数据来填充自身,这些数据是同一控件与先前请求的不同实例所留下的。

Specifically, if you look at the TextBox webcontrol, you can see that it implements the IPostBackDataHandler interface. 具体来说,如果您查看TextBox Web控件,则可以看到它实现了IPostBackDataHandler接口。 What happens is that during the beginning of the request, the page looks at all of the values in the form collection submitted by the request. 发生的情况是,在请求开始期间,页面将查看请求提交的表单集合中的所有值。 When the page locates a value in the form collection whose key matches the ID of a TextBox control, the page is able to apply that updated value to that TextBox control using the LoadPostData method of the IPostBackDataHandler interface. 当页面在表单集合中找到其键与TextBox控件的ID匹配的值时,页面可以使用IPostBackDataHandler接口的LoadPostData方法将该更新后的值应用于该TextBox控件。

It sounds like what you're doing is add several rows of data to a table and post them all back to the server at one time. 听起来您正在执行的操作是将几行数据添加到表中,并将它们一次全部发布回服务器。 You can do this, but the problem is that there are no controls on your page that can act as targets for that data. 可以执行此操作,但是问题是页面上没有控件可以用作该数据的目标。 Specifically, you need to be assigning the name attribute of your <input> tags in order for the data to be submitted to the server, but what would you put as the value of the name attribute? 具体来说,您需要分配<input>标记的name属性,以便将数据提交到服务器,但是name属性的值又是什么呢? It's not going to match up to a control on your page. 它不会与您页面上的控件匹配。 Furthermore, if you are submitting multiple rows at once, how would you distinguish one from the other? 此外,如果您一次提交多个行,您如何区分一个行?

Possible Solution 可能的解决方案

Assuming that your page, after javascript manipulation and user input, looks something like this: 假设您的页面经过javascript操作和用户输入后看起来像这样:

<table>
  <thead><tr></th>First Name</th><th>Last Name</th></tr></thead>
  <tbody>
    <tr><td><input name="FirstName[0]" value="John" /></td><td><input name="LastName[0]" value="Smith" /></td></tr>
    <tr><td><input name="FirstName[1]" value="Jane" /></td><td><input name="LastName[1]" value="Doe" /></td></tr>
    <tr><td><input name="FirstName[2]" value="Spider" /></td><td><input name="LastName[2]" value="Man" /></td></tr>
  </tbody>
</table>

In your code-behind during the postback you can access that data using code such as the following: 在回发期间的代码隐藏中,您可以使用以下代码访问该数据:

string firstName = Request.Form["FirstName[0]"];
string lastName = Request.Form["LastName[0]"];

You could also do something like this: 您还可以执行以下操作:

int index = 0;
bool dataFound;
do
{
  dataFound = false;

  string firstName = Request.Form["FirstName["+index+"]"];
  if (firstName != null)
    dataFound = true;

  string lastName = Request.Form["LastName["+index+"]"];
  if (lastName != null)
    dataFound = true;

  // do something with firstName and lastName ...

  index++;
} while (dataFound);

I believe the issue with your client side changes is that your table is not adding anything to the form's post data. 我相信与您的客户端更改有关的问题是您的表没有添加任何到窗体的发布数据。 You are manipulating the markup on the client but the markup itself is not what posts back, just the input elements and their values are posted. 您正在操纵客户端上的标记,但是标记本身不是回发的内容,只是输入元素及其值被张贴了。 Try adding a hidden input and recording the client side changes there so that the data gets posted back to the server. 尝试添加隐藏的输入并记录客户端的更改,以便将数据发布回服务器。 Then on the server side you can parse the contents of the input field to determine what changes were made. 然后,在服务器端,您可以解析输入字段的内容,以确定进行了哪些更改。

I suspect that you have a similar issue with your table that is populated through server side code. 我怀疑通过服务器端代码填充的表存在类似的问题。 If you are not storing a record of your changes to the declared markup somewhere (viewstate, session, etc.) then the server has no idea what was generated by the previous request and falls back on the declared markup. 如果您没有在某个地方(视图状态,会话等)存储对声明的标记所做的更改的记录,则服务器不知道前一个请求生成了什么,并退回到声明的标记上。

Look at some of the articles about declaring controls dynamically for a deeper explanation. 查看一些有关动态声明控件的文章,以进行更深入的说明。 http://www.4guysfromrolla.com/articles/081402-1.aspx#postadlink give a pretty good look into what is happening though the techniques and examples used are a bit dated. http://www.4guysfromrolla.com/articles/081402-1.aspx#postadlink很好地了解了正在发生的事情,尽管所使用的技术和示例有些陈旧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM