如何在ASP.NET中获得更多的控制?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (88)

我试图构建一个非常非常简单的“微型Web应用程序”。我将它放在我的深度网站C#中,它是vanilla ASP.NET 3.5(即不是MVC)。

流程非常简单:

  • 如果用户使用未指定所有参数的URL(或其中任何参数无效)输入应用程序,我只想显示用户输入控件。(只有两个。)
  • 如果用户与一个URL进入该应用确实具有所有必需的参数,我想显示的结果输入控件(使他们能够改变参数)

这是我自己设定的要求(设计和实施的混合):

  • 我希望提交使用GET而不是POST,主要是让用户可以轻松地为页面添加书签。
  • 希望网址在提交后变得愚蠢,无论它是多余的。请只提供主要网址和真实参数。
  • 理想情况下,我希望避免需要JavaScript。这个应用程序没有很好的理由。
  • 我希望能够在渲染时间和设置值等期间访问控件。特别是,如果ASP.NET无法自动执行此操作,我希望能够将控件的默认值设置为传入的参数值对我来说(在其他限制内)。
  • 我很乐意自己做所有的参数验证,而且我不需要太多的服务器端事件。在页面加载时设置所有内容非常简单,而不必将事件附加到按钮等。

大多数情况是可以的,但我还没有找到任何完全删除视图状态并保留其他有用功能的方法。使用这篇博文中的文章,我尽量避免为视图状态获取任何实际 - 但它仍然作为URL上的一个参数,看起来非常难看。

如果我使它成为一个普通的HTML表单而不是ASP.NET表单(即取出runat="server"),那么我不会获得任何魔术视图状态 - 但是我无法以编程方式访问控件。

可以通过忽略大部分ASP.NET并用LINQ to XML构建一个XML文档并实现做到这一点IHttpHandler。虽然这感觉有点低。

我意识到我的问题可以通过放宽我的限制(例如使用POST和不关心剩余参数)或使用ASP.NET MVC来解决,但是我的要求真的不合理吗?

也许ASP.NET只是不缩减到这种类型的应用程序?尽管有一个非常可能的选择:我只是很愚蠢,并且有一个非常简单的做法,我只是没有找到。

提问于
用户回答回答于

此解决方案将提供对控件的全部编程访问权限,包括控件上的所有属性。此外,提交时只有文本框值会出现在URL中,因此GET请求URL将更“有意义”

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="JonSkeetForm.aspx.cs" Inherits="JonSkeetForm" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Jon Skeet's Form Page</title>
</head>
<body>
    <form action="JonSkeetForm.aspx" method="get">
    <div>
        <input type="text" ID="text1" runat="server" />
        <input type="text" ID="text2" runat="server" />
        <button type="submit">Submit</button>
        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
                <div>Some text</div>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

然后,在代码背后,可以在PageLoad上完成需要的一切

public partial class JonSkeetForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        text1.Value = Request.QueryString[text1.ClientID];
        text2.Value = Request.QueryString[text2.ClientID];
    }
}

如果你不想要一个表单runat="server",那么你应该使用HTML控件。为您的目的而工作更容易。只需使用普通的HTML标签,并为其runat="server"提供一个ID。然后,您可以通过编程方式访问它们,并且不需要编码ViewState

唯一的缺点是你不能访问很多“有用”的ASP.NET服务器控件,比如GridViews。我Repeater在我的例子中包含了一个,因为我假设你想在结果的同一页上有字段,并且(据我所知)a Repeater是唯一的DataBound控件,它将runat="server"在Form标签中没有属性的情况下运行。

用户回答回答于

通过在FORM标签中不使用runat =“server”,你肯定是(恕我直言)在正确的轨道上。这意味着需要直接从Request.QueryString中提取值,如下例所示:

在.aspx页面本身:

<%@ Page Language="C#" AutoEventWireup="true" 
     CodeFile="FormPage.aspx.cs" Inherits="FormPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>ASP.NET with GET requests and no viewstate</title>
</head>
<body>
    <asp:Panel ID="ResultsPanel" runat="server">
      <h1>Results:</h1>
      <asp:Literal ID="ResultLiteral" runat="server" />
      <hr />
    </asp:Panel>
    <h1>Parameters</h1>
    <form action="FormPage.aspx" method="get">
    <label for="parameter1TextBox">
      Parameter 1:</label>
    <input type="text" name="param1" id="param1TextBox" value='<asp:Literal id="Param1ValueLiteral" runat="server" />'/>
    <label for="parameter1TextBox">
      Parameter 2:</label>
    <input type="text" name="param2" id="param2TextBox"  value='<asp:Literal id="Param2ValueLiteral" runat="server" />'/>
    <input type="submit" name="verb" value="Submit" />
    </form>
</body>
</html>

在代码背后:

using System;

public partial class FormPage : System.Web.UI.Page {

        private string param1;
        private string param2;

        protected void Page_Load(object sender, EventArgs e) {

            param1 = Request.QueryString["param1"];
            param2 = Request.QueryString["param2"];

            string result = GetResult(param1, param2);
            ResultsPanel.Visible = (!String.IsNullOrEmpty(result));

            Param1ValueLiteral.Text = Server.HtmlEncode(param1);
            Param2ValueLiteral.Text = Server.HtmlEncode(param2);
            ResultLiteral.Text = Server.HtmlEncode(result);
        }

        // Do something with parameters and return some result.
        private string GetResult(string param1, string param2) {
            if (String.IsNullOrEmpty(param1) && String.IsNullOrEmpty(param2)) return(String.Empty);
            return (String.Format("You supplied {0} and {1}", param1, param2));
        }
    }

这里的技巧是我们在文本输入的value =“”属性中使用了ASP.NET Literals,所以文本框本身不需要runat =“server”。然后将结果包装在ASP:Panel中,并在页面加载时设置Visible属性,具体取决于是否要显示任何结果。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励