建议建立一个动态的;“高级搜索”;ASP.NET中的控件

建议建立一个动态的;“高级搜索”;ASP.NET中的控件,asp.net,search,dynamic,viewstate,Asp.net,Search,Dynamic,Viewstate,我正在ASP.NET应用程序中构建“高级搜索”界面。我不需要写这篇文章,但是关于动态控件和视图状态,我遇到了一个特殊的问题。我想知道如何处理这个问题的一些方向。我的情况如下: 成分: 一组可用的API对象,表示实体、字段和搜索,用于构造搜索、生成SQL和返回结果。所以这些都处理好了 ASP.NET3.5 所需的界面功能: (1) 在初始页面加载时,该接口将获得一个预配置的搜索对象和一组SearchCriteria对象。它将它们绑定到一组控件中(参见上图) 有些搜索项目比较简单,如: 字段(

我正在ASP.NET应用程序中构建“高级搜索”界面。我不需要写这篇文章,但是关于动态控件和视图状态,我遇到了一个特殊的问题。我想知道如何处理这个问题的一些方向。我的情况如下:

成分:

  • 一组可用的API对象,表示实体、字段和搜索,用于构造搜索、生成SQL和返回结果。所以这些都处理好了
  • ASP.NET3.5
所需的界面功能:

(1) 在初始页面加载时,该接口将获得一个预配置的搜索对象和一组SearchCriteria对象。它将它们绑定到一组控件中(参见上图)

  • 有些搜索项目比较简单,如:

    字段(DropDownList)|运算符(DropDownList)|值(文本框)

  • 某些字段类型的搜索条件控件具有存储在viewstate中的重要信息,例如:

    字段(DropDownList)|运算符(DropDownList)|值(DropDownList),其中“值”DropDownList由数据库查询填充

  • 某些字段是对其他实体的查找,这会导致一系列字段选择器,如:

    字段(DropDownList)字段(DropDownList)|运算符(DropDownList)|值

(2) 用户通过以下方式修改搜索:

  • 通过单击相应的按钮添加和删除搜索条件
  • 通过更改字段、运算符或值来配置现有条件。对字段或运算符的更改将要求控件通过更改可用的运算符、将“值”输入控件更改为其他类型或在选择/取消选择查找类型字段的情况下从“字段”部分添加/删除下拉列表来重新配置自身
(3) 最后,用户点击“搜索”查看结果

问题:

如果您正在回答这个问题,您可能已经知道,动态添加到页面的控件将在回发时消失。我已经创建了一个UserControl,它可以操纵控件集合,并整洁地完成上面的步骤(1),如您在附加的图像中所看到的。(显然,在这一点上,我并不关心风格。)

但是在回发时,所有控件都消失了,我的搜索API对象也消失了。如果我可以让动态生成的控件集合在ViewState中正常运行,我就可以检查回发时的控件,重建搜索对象,然后巧妙地处理控件事件

可能的解决方案

  • 我可以将搜索对象序列化并将其存储在viewstate中。然后在页面加载时,我可以抓取它并在页面加载时重建控件集合。但是,我不确定这是否能很好地处理引发事件的控件,以及包含数据库数据的下拉列表的viewstate会发生什么情况—我能取回它吗?对于我来说,每次回发都要重新查询数据库是非常不可取的

  • 我可以为这类东西开发一个自定义服务器控件()。。。但这对我来说是一个新的主题,需要一些学习,而且我不完全确定定制服务器控件是否能够更好地处理非固定控件集合。有人知道吗

  • 我在想,我可能可以使用数据绑定控件来实现这一点——例如,我可以将我的标准集合绑定到具有固定控件集合的中继器(可能隐藏未使用的“值”控件,使用内部中继器来显示“字段”下拉列表)。然后所有的信息都会保持在视图状态。。。对吧?

  • 任何新的想法都将不胜感激

谢谢你的帮助。
b、 Fandango

因为已经有两个小时没有其他人尝试过这一点,所以我将提出一个完全不依赖viewstate(或ASP.NET模型的回发)的解决方案

如果您使用jQuery获取所有输入值,而不是对页面(或新的results.aspx页面)进行回发,会怎么样?或者,您可以使整个过程异步化,对web方法执行Ajax请求,获得结果,并根据需要在客户端进行填充

不幸的是,您必须重建用于构建搜索查询的控件类型,因为数据不会随viewstate一起传递。但我想,无论如何,您都必须将输入数据转换为查询表单

有关使用jQuery访问ASP.NET页面方法的详细信息,请阅读。请记住,页面方法必须是静态的(这很容易疏忽)

我不确定您在服务器端构造查询时正在做什么,但我强烈推荐LINQ。我以前也做过类似的“高级搜索”功能,经过几次不同的尝试后,我发现LINQ是解决这个问题的一个极好的工具,不管我是用LINQtoSQL访问SQL还是仅仅访问内存中的对象集合

这非常有效,因为1)LINQ是延迟执行的,2)LINQ查询返回另一个可查询的对象。这里的含义是,当您从输入构造LINQ查询时,您可以将它们链接在一起,而无需将单个大规模子句转换为SQL或您正在使用的任何后台(我的一次尝试是用字符串构造SQL子句,但仍然通过SQLParameters传递输入数据以进行SQL注入保护——当手工制作的LINQ更容易理解和实现时,这是一件混乱而复杂的事情)

例如:

List<string> data; // or perhaps your a DB Context for LINQtoSQL?

var query = data.Where(item => item.contains("foo"));

if( {user supplies length search option} )
    query = query.Where(item => item.Length < 5);

// etc, etc.

// LINQ doesn't do anything until the query is iterated, at which point
// it will construct the SQL statement without you worrying about details or parameter binding
foreach(string value in query)
    ; // do something with the results
List data;//或者您的数据库上下文是用于LINQtoSQL的?
var query=data.Where(item=>item.contains(“foo”);
if({用户提供长度searc