programing

어떻게 하면 ASP에서 더 많은 권한을 가질 수 있습니까?NET?

mailnote 2023. 5. 6. 15:18
반응형

어떻게 하면 ASP에서 더 많은 권한을 가질 수 있습니까?NET?

저는 매우 간단한 "마이크로 웹 앱"을 구축하려고 합니다. 제가 그것을 완성한다면 스택 오버플로의 몇몇 사람들에게 관심을 가질 것이라고 생각합니다.저는 그것을 Vanilla ASP인 Depth의 제 C# 사이트에서 호스팅하고 있습니다.NET 3.5(즉, MVC가 아님).

흐름은 매우 간단합니다.

  • 사용자가 모든 매개 변수를 지정하지 않은 URL로 앱을 입력하는 경우(또는 잘못된 매개 변수가 있는 경우) 사용자 입력 컨트롤만 표시하고 싶습니다(두 개만 있습니다).
  • 사용자가 필요한 매개 변수가 모두 포함된 URL로 앱을 입력하는 경우 결과와 입력 컨트롤을 표시하고 싶습니다(파라미터를 변경할 수 있도록).

다음은 저의 자체 요구사항(설계와 구현의 혼합)입니다.

  • 저는 주로 사용자들이 페이지를 쉽게 북마크할 수 있도록 POST 대신 GET를 사용하는 제출을 원합니다.
  • 저는 URL이 제출 후 불필요한 조각과 함께 바보처럼 보이는 것을 원하지 않습니다.메인 URL과 실제 파라미터만 부탁드립니다.
  • 이상적으로는 자바스크립트가 전혀 필요하지 않습니다.이 앱에는 그럴 만한 이유가 없습니다.
  • 렌더 시간 동안 컨트롤에 액세스하고 값을 설정하는 등의 작업을 수행할 수 있습니다.특히 ASP인 경우 전달된 매개 변수 값으로 컨트롤의 기본값을 설정할 수 있기를 원합니다.NET은 다른 제한 내에서 자동으로 이 작업을 수행할 수 없습니다.
  • 모든 파라미터 검증을 제가 직접 할 수 있어서 기쁘고, 서버 사이드 이벤트는 별로 필요하지 않습니다.버튼 등에 이벤트를 첨부하는 대신 페이지 로드에 모든 것을 설정하는 것은 정말 간단합니다.

대부분은 괜찮지만 보기 상태를 완전히 제거하고 나머지 유용한 기능을 유지할 수 있는 방법을 찾지 못했습니다.블로그 게시물의 게시물을 사용하여 보기 상태에 대한 실제 값을 얻는 것을 피할 수 있었지만, 여전히 URL의 매개 변수로 끝나 정말 보기 흉하게 보입니다.

ASP 대신 일반 HTML 양식으로 만들면 됩니다. 양식 NET을 꺼냄)runat="server"그러면 마법의 보기 상태가 나타나지 않지만 프로그래밍 방식으로 컨트롤에 액세스할 수 없습니다.

ASP의 대부분을 무시함으로써 이 모든 것을 할 수 있었습니다.NET 및 LINQ to XML을 사용한 XML 문서 구축 및 구현IHttpHandler그래도 좀 낮은 느낌이 드네요.

저는 제 제약을 완화하거나(예: POST를 사용하고 잉여 매개 변수를 신경 쓰지 않음) ASP를 사용하여 문제를 해결할 수 있다는 것을 깨달았습니다.NET MVC, 하지만 제 요구 사항이 정말 불합리한가요?

아마도 ASP.NET은 이런 종류의 앱으로 확장되지 않습니까?하지만 다음과 같은 가능성 있는 대안이 있습니다.저는 그저 어리석게 굴 뿐이고, 제가 발견하지 못한 완벽하게 간단한 방법이 있습니다.

아무 생각 없어요, 누구?(힘센 사람들이 어떻게 쓰러졌는지 등에 대한 큐 댓글.괜찮습니다. 제가 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"신분증을 제시해 주세요그런 다음 프로그래밍 방식으로 액세스하고 코드를 작성할 수 있습니다.ViewState.

유일한 단점은 많은 "도움이 되는" ASP에 액세스할 수 없다는 것입니다. 서버 은 NET 서버같제다니어합과 같습니다.GridView는 포했습다니를 했습니다.Repeater ( " 예서면나, 왜와결같과페내은당필이가에있가싶드지고고어정고하다한는고를지알로가기신내이냐는에하내▁a▁in▁on있가▁because▁i)▁(고▁my▁the▁fields▁example▁and고알는하▁as▁to▁you가▁have▁want▁(▁that▁the▁a▁resultsto로'▁assuming▁page▁same정) a"로 되어 있습니다.Repeater는 DataBound 하지 않고 한 DataBound 컨트롤입니다.runat="server"속성을 입력합니다.

폼 태그에 runat="server"를 사용하지 않는 것은 분명 올바른 방향으로 가고 있는 (IMHO) 것입니다.즉, 요청에서 값을 추출해야 합니다.그러나 다음 예와 같이 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));
        }
    }

여기서 비결은 우리가 ASP를 사용하고 있다는 것입니다.텍스트 입력의 값=" 속성 안에 있는 NET 리터럴은 텍스트 입력 자체를 ="server"에서 실행할 필요가 없습니다.그런 다음 결과가 ASP:Panel 내부로 감겨지고 결과를 표시할지 여부에 따라 페이지 로드 시 Visible 속성이 설정됩니다.

좋아요, 존, 상태 문제를 먼저 봅니다.

2.0 이후 내부 코드 변경이 있는지 확인하지 못했지만 몇 년 전 뷰 상태를 제거하는 작업은 다음과 같습니다.실제로 숨겨진 필드는 HtmlForm 내부에서 하드 코딩되므로 새 필드를 파생하여 직접 렌더링 작업에 참여해야 합니다.일반적인 오래된 입력 컨트롤을 고수하는 경우 __eventtarget 및 __eventtarget을 제외할 수도 있습니다(클라이언트에 JS를 요구하지 않는 데도 도움이 되므로 이를 원할 것입니다).

protected override void RenderChildren(System.Web.UI.HtmlTextWriter writer)
{
    System.Web.UI.Page page = this.Page;
    if (page != null)
    {
        onFormRender.Invoke(page, null);
        writer.Write("<div><input type=\"hidden\" name=\"__eventtarget\" id=\"__eventtarget\" value=\"\" /><input type=\"hidden\" name=\"__eventargument\" id=\"__eventargument\" value=\"\" /></div>");
    }

    ICollection controls = (this.Controls as ICollection);
    renderChildrenInternal.Invoke(this, new object[] {writer, controls});

    if (page != null)
        onFormPostRender.Invoke(page, null);
}

그래서 당신은 그 3개의 정적 MethodInfo를 얻고 그들을 불러내어 그 뷰 상태 부분을 빼냅니다;)

static MethodInfo onFormRender;
static MethodInfo renderChildrenInternal;
static MethodInfo onFormPostRender;

양식의 유형 생성자는 다음과 같습니다.

static Form()
{
    Type aspNetPageType = typeof(System.Web.UI.Page);

    onFormRender = aspNetPageType.GetMethod("OnFormRender", BindingFlags.Instance | BindingFlags.NonPublic);
    renderChildrenInternal = typeof(System.Web.UI.Control).GetMethod("RenderChildrenInternal", BindingFlags.Instance | BindingFlags.NonPublic);
    onFormPostRender = aspNetPageType.GetMethod("OnFormPostRender", BindingFlags.Instance | BindingFlags.NonPublic);
}

질문이 맞다면 양식의 작업으로 POST를 사용하지 않으려는 것입니다. 따라서 다음과 같은 방법을 사용됩니다.

protected override void RenderAttributes(System.Web.UI.HtmlTextWriter writer)
{
    writer.WriteAttribute("method", "get");
    base.Attributes.Remove("method");

    // the rest of it...
}

거의 이 정도인 것 같아요.어떻게 되어 가는지 나에게 알려줘.

편집: 페이지 보기 상태 메서드를 잊어버렸습니다.

따라서 사용자 정의 양식: HtmlForm은 새로운 추상(또는 그렇지 않음) 페이지: 시스템을 얻습니다.Web.UI.페이지:p

protected override sealed object SaveViewState()
{
    return null;
}

protected override sealed void SavePageStateToPersistenceMedium(object state)
{
}

protected override sealed void LoadViewState(object savedState)
{
}

protected override sealed object LoadPageStateFromPersistenceMedium()
{
    return null;
}

이 경우에는 페이지를 봉인할 수 없기 때문에 메소드를 봉인합니다(추상적이지 않더라도 스콧 거스리가 다른 페이지로 포장할 것입니다:P). 하지만 양식은 봉인할 수 있습니다.

POST를 제거하는 것이 아니라 양식이 POST될 때 적합한 GET URL로 리디렉션하는 것을 고려해 본 적이 있습니까?즉, GET 및 POST를 모두 수락하지만 POST 시 GET 요청을 구성하고 이 요청으로 리디렉션합니다.페이지에 독립적으로 설정하려면 페이지에서 처리하거나 HttpModule을 통해 처리할 수 있습니다.이렇게 하면 일이 훨씬 쉬워질 것 같습니다.

편집: 페이지에 EnableViewState="false"가 설정되어 있다고 가정합니다.

나는 라우팅을 처리하는 HTTP 모듈을 만들 것입니다(MVC와 비슷하지만 정교하지는 않습니다, 단지 몇 개).if진술서)를 제출합니다.aspx또는ashx페이지들aspx페이지 템플릿을 수정하는 것이 더 쉽기 때문에 선호됩니다.나는 사용하지 않을 것입니다.WebControls에서aspx하지만.그저.Response.Write.

그런데, 일을 단순화하기 위해 모듈에서 매개 변수 검증을 수행하고(아마도 라우팅과 코드를 공유하기 때문에) 저장할 수 있습니다.HttpContext.Items그런 다음 페이지에 렌더링합니다.이것은 모든 벨과 호루라기 없이 MVC와 거의 비슷하게 작동할 것입니다.이것은 제가 ASP 전에 많이 했던 일입니다.NET MVC 일 수.

저는 페이지 클래스를 완전히 포기하고 URL을 기반으로 한 큰 스위치 케이스로 모든 요청을 처리할 수 있어서 정말 기뻤습니다.모든 "페이지"는 html 템플릿과 c# 객체가 됩니다.템플릿 클래스는 키 컬렉션과 비교하는 일치 대리자가 있는 정규식을 사용합니다.

이점:

  1. 정말 빠릅니다. 재컴파일 후에도 거의 지연이 없습니다(페이지 클래스가 커야 함).
  2. 제어가 매우 세분화되어 있습니다(SEO에 매우 적합하며, DOM이 JS와 잘 작동하도록 설계).
  3. 프레젠테이션은 논리와 별개입니다.
  4. jQuery는 html을 완전히 제어합니다.

부머:

  1. 단순한 것은 단일 텍스트 상자가 여러 곳에서 코드를 필요로 한다는 점에서 조금 더 오래 걸리지만, 정말 잘 확장됩니다.
  2. 내가 보기 상태를 볼 때까지 페이지 뷰로 그것을 하는 것은 항상 유혹적입니다. (으윽) 그러고 나서 나는 다시 현실로 돌아갑니다.

Jon, 토요일 아침에 SO에서 무엇을 합니까:)?

나는 ASP가 다음과 같이 생각했습니다.리피터 제어는 더 이상 사용되지 않습니다.

ASP.NET 템플릿 엔진은 좋지만 for 루프를 사용하여 쉽게 반복할 수 있습니다.

<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>
    <% foreach( var item in dataSource ) { %>
        <div>Some text</div>   
    <% } %>
</div>
</form>

ASP.NET Forms는 괜찮은 편입니다. Visual Studio의 상당한 지원을 받고 있지만 이 Runat="server"라는 것은 잘못된 것입니다.상태 보기 대상.

무엇이 ASP를 만드는지 살펴보시기를 제안합니다.ASP에서 멀어지는 NET MVC 너무 좋아요.NET Forms는 모든 것을 버리지 않고 접근합니다.

NHaml과 같은 사용자 정의 보기를 컴파일하기 위해 자체 빌드 공급자 항목을 작성할 수도 있습니다.저는 당신이 여기서 더 많은 통제권을 찾고 단순히 ASP에 의존해야 한다고 생각합니다.HTTP를 래핑하고 CLR 호스팅 환경으로 사용하기 위한 NET 런타임입니다.통합 모드를 실행하면 HTTP 요청/응답도 조작할 수 있습니다.

언급URL : https://stackoverflow.com/questions/431296/how-can-i-take-more-control-in-asp-net

반응형