如何在ASP.NET中进行更多控制?

Jon*_*eet 123 .net asp.net viewstate .net-3.5

我正在尝试构建一个非常非常简单的"微网络应用程序",如果我完成它,我怀疑它会引起一些Stack Overflow的兴趣.我在深度站点的C#中托管它,这是vanilla ASP.NET 3.5(即不是MVC).

流程非常简单:

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

以下是我的自我要求(设计和实施的混合):

  • 我希望提交使用GET而不是POST,主要是因为用户可以轻松地为页面添加书签.
  • 希望URL在提交后最终看起来很傻,上面有一些无关紧要的东西.请只是主要的URL和真实的参数.
  • 理想情况下,我想完全避免使用JavaScript.在这个应用程序中没有充分的理由.
  • 我希望能够在渲染时间和设置值等访问控件.特别是,我希望能够将控件的默认值设置为传入的参数值,如果ASP.NET不能自动执行此操作对我来说(在其他限制范围内).
  • 我很高兴自己做所有的参数验证,我不需要太多的服务器端事件.在页面加载上设置所有内容而不是将事件附加到按钮等非常简单.

大多数情况都没问题,但我没有找到任何完全删除视图状态并保留其余有用功能的方法.使用此博客文章中的帖子,我设法避免获得视图状态的任何实际 - 但它仍然最终作为URL上的参数,看起来非常难看.

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

可以通过忽略大部分ASP.NET并使用LINQ to XML构建XML文档并实现完成所有这些工作IHttpHandler.虽然感觉有点低.

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

也许ASP.NET只是不缩小到这种应用程序?虽然有一个非常可能的替代方案:我只是愚蠢,并且有一个非常简单的方法,我只是没有找到.

任何想法,任何人?(提示评论强大如何堕落等等.那很好 - 我希望我从未声称自己是一名ASP.NET专家,因为事实恰恰相反......)

Dan*_*ert 76

此解决方案将为您提供对控件的完全编程访问,包括控件上的所有属性.此外,提交时,只有文本框值会显示在网址中,因此您的GET请求网址会更"有意义"

<%@ 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>
Run Code Online (Sandbox Code Playgroud)

然后在您的代码隐藏中,您可以在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];
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想要具有的表单,runat="server"则应使用HTML控件.为您的目的而工作更容易.只需使用常规HTML标记并放置runat="server"并为其提供ID.然后你可以通过编程方式访问它们无需编写代码ViewState.

唯一的缺点是你将无法访问许多像" GridViews "这样的"有用的"ASP.NET服务器控件.我Repeater在我的示例中包含了一个,因为我假设您希望将字段放在与结果相同的页面上(据我所知)a Repeater是唯一一个runat="server"在Form标记中没有属性的情况下运行的DataBound控件.

  • 看起来你应该用经典的asp写它! (14认同)

Dyl*_*tie 12

你肯定(恕我直言)在你的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>
Run Code Online (Sandbox Code Playgroud)

并在代码隐藏中:

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));
        }
    }
Run Code Online (Sandbox Code Playgroud)

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