anterior : <rewriter>
< reescrever url = " ^/Usuário/(d+)$ " para = " ~/User.aspx?id=$1 " processando = " parar " />
< reescrever url = " ^/Usuário/(w+)$ " to = " ~/User.aspx?name=$1 " processando = " parar " />
</ rewriter >
Quando o usuário solicitar "/User/jeffz", o código que aparece na página será <form action="/User.aspx?name=jeffz" />. a página O valor atual de Request.Url.PathAndQuery será usado para obter a ação do elemento do formulário. Isso faz com que "User.aspx?name=jeffz" apareça na barra de endereço uma vez no PostBack, e esse endereço pode não ser capaz de solicitar o recurso correto (porque pode ser reescrito em outro lugar ou devido a relacionamentos no nível do diretório). tal recurso). No artigo anterior " UpdatePanel e UrlRewrite ", eu disse que esse problema pode ser resolvido adicionando uma linha de código JavaScript no final da página:
< script language ="javascript" type ="text/javascript">
document.getElementsByTagName( "form" )[0].action = window.location;
</script> O propósito
desta linha de código é muito óbvio. Altere a ação do formulário para window.location (ou seja, o caminho na barra de endereço do navegador), para que quando a página executar o PostBack, o endereço de destino seja. seja o endereço antes da URL Rewrite . Essa abordagem pode fazer o programa funcionar normalmente, mas realmente não me satisfaz. Por que?
Porque é muito feio.
Porque ainda expomos o endereço após a reescrita de URL para o cliente. Contanto que o usuário instale um sniffer HTTP (como o famoso Fiddler) ou selecione diretamente visualizar o arquivo de origem no IE, nosso endereço de destino será exibido na frente do usuário sem qualquer ocultação. Como podemos informar aos usuários nossas regras de reescrita? Devemos resolver este problema. A solução é muito simples e já muito popular, que é utilizar o Control Adapter para alterar o comportamento da geração do Form. Mas o que me deixa estranho é que todas as buscas por este Adaptador de Controle na Internet são versões VB.NET, mas a linguagem C# promovida principalmente pela Microsoft não pode ser encontrada. Embora não seja difícil reescrever, desde que você entenda um pouco da sintaxe do VB.NET, afinal ainda é um trabalho extra. Então vou postar o código da versão C# deste Adaptador agora para que amigos possam usá-lo diretamente:
namespace Sample.Web.UI.Adapters
{
classe pública FormRewriterControlAdapter :
System.Web.UI.Adapters.ControlAdapter
{
substituição protegida void Render (gravador HtmlTextWriter )
{
base .Render( new RewriteFormHtmlTextWriter (escritor));
}
}
classe pública RewriteFormHtmlTextWriter : HtmlTextWriter
{
público RewriteFormHtmlTextWriter (escritor HtmlTextWriter )
: base (escritor)
{
este .InnerWriter = escritor.InnerWriter;
}
público RewriteFormHtmlTextWriter (escritor TextWriter )
: base (escritor)
{
este .InnerWriter = escritor;
}
substituição pública void WriteAttribute (nome da string , valor da string , bool fEncode)
{
if (nome == "ação" )
{
Contexto HttpContext = HttpContext .Current;
if (context.Items[ "ActionAlreadyWritten" ] == null )
{
valor = contexto.Request.RawUrl;
context.Items[ "ActionAlreadyWritten" ] = true ;
}
}
base .WriteAttribute(nome, valor, fEncode);
}
}
}
Simplificando, este Adaptador de Controle estava aguardando o momento em que o atributo "action" fosse gerado e alterasse o valor para o atributo RawUrl do objeto Request atual. Este atributo é determinado quando o ASP.NET recebe pela primeira vez a solicitação do IIS. Ele não será alterado com a operação de reescrita subsequente em BeginRequest. Portanto, precisamos apenas gerar o RawUrl para a ação do formulário para resolver o problema de alteração de endereço do PostBack.
Porém, para que este Adaptador de Controle tenha efeito, você também deve criar um arquivo de navegador no projeto Web, como "App_BrowsersForm.browser", e escrever o seguinte código nele:
< navegadores >
< navegador refID = " Padrão " >
<controlAdaptadores>
< adaptador controlType = " System.Web.UI.HtmlControls.HtmlForm "
adaptadorType = " Sample.Web.UI.Adapters.FormRewriterControlAdapter " />
</controlAdapters>
</ navegador >
</ browsers >
Neste ponto, o problema das alterações de endereço PostBack causadas pela reescrita de URL no nível ASP.NET foi perfeitamente resolvido - espere, por que deveríamos enfatizar o "nível ASP.NET"? Isso mesmo, porque se você reescrever URL no nível IIS, esse problema ainda existirá. Por exemplo, se você usar IIRF para reescrita de URL e ativar o adaptador de controle acima, ainda descobrirá que o endereço de PostBack na página é diferente do endereço solicitado pelo cliente. O RawUrl também se tornou "desleal"? Isso não se deve ao RawUrl, mas é determinado pelo mecanismo ASP.NET. Para explicar esse problema, vamos dar uma olhada novamente no diagrama do primeiro artigo " IIS e ASP.NET ":
A reescrita de URL no nível do IIS ocorre antes da etapa 2 na imagem acima. Como foi reescrita, o seletor ISAPI do IIS entregará a solicitação ao ASPNET ISAPI para processamento. Em outras palavras, quando o IIS entrega a solicitação ao mecanismo ASP.NET para processamento, as informações que o ASP.NET obtém do IIS já são o endereço após a reescrita de URL (por exemplo, /User.aspx?name=jeffz), portanto, não importa Não importa onde o ASP.NET processe a solicitação, ele não poderá saber a URL quando o IIS recebeu a solicitação.
Em outras palavras, não há realmente nada que possamos fazer a respeito.
No entanto, as quatro palavras "realmente não há como" são condicionais. Para ser mais completo, deveria ser: "confiar no próprio ASP.NET" é de fato "não há como". Mas e se o IIS nos ajudar ao realizar a reescrita de URL? Como um componente de código aberto maduro, o IIRF sabe naturalmente que o mecanismo ASP.NET e até mesmo todos os manipuladores ISAPI precisam de sua ajuda. Ele naturalmente conhece o princípio de "fazer alterações quando fizer alterações", por isso aprendeu a armazenar o endereço original. Recursos na variável de servidor HTTP_X_REWRITE_URL. Porém, o IIRF não fará isso "conscientemente" (que cansativo), então precisamos lembrá-lo no arquivo de configuração:
RewriteRule ^/User/(d+)$ /User.aspx?id=$1 [I, L , U ]
RewriteRule ^/User/(w+)$ /User.aspx?name=$1 [I, L, U]
Observe que usamos um modificador adicional. Adicionar U à coleção Modifier indica que precisamos do IIRF para armazenar o endereço original antes da URL Rewrite na variável do servidor HTTP_X_REWRITE_URL. Agora podemos obter esse valor no ASP.NET, então modificamos o método WriteAttribute no código anterior do Adaptador de Controle da seguinte maneira:
public override void WriteAttribute( string name, string value, bool fEncode)
{
if (nome == "ação" )
{
Contexto HttpContext = HttpContext .Current;
if (context.Items[ "ActionAlreadyWritten" ] == null )
{
valor = context.Request.ServerVariables[ "HTTP_X_REWRITE_URL" ]
??contexto.Request.RawUrl;
context.Items[ "ActionAlreadyWritten" ] = true ;
}
}
base .WriteAttribute(nome, valor, fEncode);
}
Agora o valor da ação não é simplesmente obtido do atributo RawUrl, mas tenta obter o valor da variável HTTP_X_REWRITE_URL da coleção ServerVariables, pois ali está armazenado o endereço da solicitação original recebida pelo IIS.
Neste ponto, os principais tópicos sobre reescrita de URL foram abordados. No próximo artigo, que é o último artigo desta série, focaremos nas diferenças em alguns detalhes causadas pelo uso de diferentes níveis de reescrita de URL e nos pontos relevantes de. observação.