Home > Messages > ASP.NET > Changing where a web form posts back to, and dealing with URL Rewrites
|
|
|
Kurt
Mackey
|
|
3/24/2003 12:20:28 AM
|
Not rated
|
I'm using ASP.NET's built in rewrite functionality to make "pretty" URLs for a specific web application. The "pretty" URL (www.blah.com/Content/Forms.aspx) turns into a typical URL with query string parameters (Default.aspx?ContentPath=/Forms) to display the actual content.
The problem I'm running into is that the postback action is set to the non-pretty URL. Is there any way to override where it posts back to so I can retain the better URLs?
|
|
Kurt
Mackey
|
|
3/24/2003 4:31:24 PM
|
Not rated
|
Hrm... interesting new problem: when I visit /Content/Forms.aspx (turns into /Default.aspx?ContentPath=/Forms), and do anything that triggers a post back, it attempts to post back to /Content/Default.aspx?ContentPath=/Forms. Since /Content is the portion of the path that's triggering the URL rewrite, the PostBack URL actually turns into /Default.aspx?ContentPath=Default, which isn't good.
I hope all that was clear enough, and any solution recommendations would be much appreciated.
|
|
Kurt
Mackey
|
|
3/25/2003 12:26:36 AM
|
Not rated
|
I'll just continue talking to myself for a bit...
I finally figured out what I needed to do. I created my own "XHtmlForm" (catchy name, isn't it?) that inherits from System.Web.UI.HtmlControls.HtmlForm and then created my own RenderAttributes method that overrides the original. The RenderAttributes method takes a HtmlTextWriter as its argument, so I can use HtmlTextWriter.WriteAttribute to output any attributes I need, including the "new" action attribute.
I'm hoping to inherit all the WebControls and HtmlControls I normally use and make them spit out completely XHTML compliant markup.
|
|
Jacob
Andersen
|
|
6/19/2003 5:22:02 AM
|
Not rated
|
Hello Kurt, just want to say that your not alone anymore.
And then I would like some help.
I have tried to do what you have done, but im running indto a problem.
With my custom form the output will be: <form method="post" action="http://demoshop.test.net/Productlist/2x1.aspx">
The code: -------------------- using System; using System.Web; using System.Web.UI;
namespace Test.URLreplacer { public class URLreplacerForm : System.Web.UI.HtmlControls.HtmlForm { protected override void RenderAttributes(HtmlTextWriter writer) { base.Attributes.Remove("action"); if(HttpContext.Current.Items["RewriteURL"] != null) { base.Attributes.Add("action", HttpContext.Current.Items["RewriteURL"].ToString()); } else{ base.Attributes.Add("action", HttpContext.Current.Request.Url.ToString()+"s" ); } base.Attributes.Render(writer); } } } ----------------------
But what I do need to get is: <form method="post" action="http://demoshop.test.net/Productlist/2x1.aspx" name="_ctl0:_ctl0:Form1" method="post" language="javascript" onsubmit="if (DefaultButton_RequireOwnPostback(this) ) { return false; }; " id="_ctl0__ctl0_Form1">
Which is the output when I use my normal form control, and where the action attribute is changed.
As you can see I have tried to remove action from Attributes and insert it with the url that I need it to be.
I have tried some different ways to do this, including calling base.RenderAttributes afterwards. Which totally ignores what I have set in the attribute collection.
Do you have a solution to this. I really hope so.
|
|
Jacob
Andersen
|
|
6/19/2003 5:52:29 AM
|
Not rated
|
I just worked a little more with my form control and changed it to the following which works great.
I don't like that I need to find the action attribute in the string and then change it, but it works.
If you or any others have a better solution or a solution where its not needed to change directly in the rendering output, I would be happy to see it.
Here is my code: protected override void RenderAttributes(HtmlTextWriter writer) { if(HttpContext.Current.Items["RewriteURL"] != null) {
System.Text.StringBuilder sb = new System.Text.StringBuilder(); System.IO.StringWriter sw = new System.IO.StringWriter( sb ); System.Web.UI.Html32TextWriter w = new System.Web.UI.Html32TextWriter(sw); base.RenderAttributes( w ); string html = sb.ToString(); w.Close(); int start = html.IndexOf("action=\"") + 8; int end = html.IndexOf("\"", start); html = html.Remove( start, end - start ); html = html.Insert( start, HttpContext.Current.Items["RewriteURL"].ToString()); writer.Write( html );
} else{ base.RenderAttributes(writer); } }
|
|
Chris
Allen
|
|
6/26/2003 11:05:25 AM
|
Not rated
|
I have exactly the same problem, we are using urlrewrites to make our page urls really clean however when the asp.net form renders the action goes to the nasty looking url, another problem is that a spider might see the two pages as having duplicated content and it will leak page rank...
I am relativly new to asp.net but have got the rewrite working fine just need page to submit the nice url on postback.
|
|
Chris
Allen
|
|
6/26/2003 11:05:54 AM
|
Avg. Rating: 1 by 1 Users
|
I have exactly the same problem, we are using urlrewrites to make our page urls really clean however when the asp.net form renders the action goes to the nasty looking url, another problem is that a spider might see the two pages as having duplicated content and it will leak page rank...
I am relativly new to asp.net but have got the rewrite working fine just need page to submit the nice url on postback.
|
|
Kurt
Mackey
|
|
8/23/2003 7:17:58 PM
|
Not rated
|
For future reference, you don't actually have to find the "action" attribute and replace it. I chose to not call the base.RenderAttributes function and handle all the attributes myself. This help's me force compliance in the controls by not rendering some goofy attribute that's not in the XHTML spec. Here's the class I used:
[DefaultProperty("Text"),
ToolboxData("<{0}:XHtmlForm runat=server></{0}:XHtmlForm>")]
public class XHtmlForm : System.Web.UI.HtmlControls.HtmlForm
{
private string postUrl;
[Bindable(false),
Category("Behavior"),
DefaultValue("")]
public string PostUrl
{
get{ return postUrl; }
set{ postUrl = value; }
}
protected override void RenderAttributes(HtmlTextWriter output)
{
if(postUrl == null)
{
base.RenderAttributes(output);
}
else
{
output.WriteAttribute ("action", this.postUrl, true);
output.WriteAttribute ("method", base.Method);
output.WriteAttribute ("id", base.ID);
output.WriteAttribute ("name", base.Name);
if(base.Enctype != "")
output.WriteAttribute ("enctype", base.Enctype);
}
}
}
|
I just instantiate it like so:
| |
<%@ Register TagPrefix="Custom" Namespace="MackeyBros.ContentSystem.CompliantControls" assembly="MackeyBros.ContentSystem"%>
|
| |
<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="MackeyBros.ContentSystem._Default" %>
|
<!doctype html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
</head>
<body>
<custom:xhtmlform runat="server" id="PageletForm"></custom:xhtmlform>
</body>
</html>
|
|
|
Kurt
Mackey
|
|
8/23/2003 7:26:16 PM
|
Not rated
|
I have tried some different ways to do this, including calling base.RenderAttributes afterwards. Which totally ignores what I have set in the attribute collection.
Do you have a solution to this. I really hope so.
Unfortunately, there's no real solution for this. The base.RenderAttributes uses and internal property to set the "action", removing anything you already put in it. The only real option is recreating the functionality of the RenderAttributes function. Here is the Mono class:
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
namespace System.Web.UI.HtmlControls{
public class HtmlForm : HtmlContainerControl{
private static string SmartNavIncludeScriptKey = "SmartNavIncludeScript";
public HtmlForm(): base("form"){}
protected override void RenderAttributes(HtmlTextWriter writer){
writer.WriteAttribute("name", RenderedName);
Attributes.Remove("name");
writer.WriteAttribute("method", Method);
Attributes.Remove("method");
writer.WriteAttribute("action", Action, true);
Attributes.Remove("action");
if (Enctype != null){
writer.WriteAttribute ("enctype", Enctype);
Attributes.Remove ("enctype");
}
if (ID == null){
writer.WriteAttribute("id",ClientID);
}
base.RenderAttributes(writer);
}
protected override void Render(HtmlTextWriter output){
if (Page.SmartNavigation == false){
base.Render (output);
return;
}
((IAttributeAccessor) this).SetAttribute("_smartNavigation","true");
HttpBrowserCapabilities browserCap = Context.Request.Browser;
if (browserCap.Browser.ToLower() != "ie" && browserCap.MajorVersion < 5){
base.Render(output);
return;
}
output.WriteLine("<IFRAME ID=_hifSmartNav NAME=_hifSmartNav STYLE=display:none ></IFRAME>");
if (browserCap.MinorVersion < 0.5 && browserCap.MajorVersion != 5)
Page.RegisterClientScriptFile("SmartNavIncludeScript","JScript","SmartNavIE5.js");
else if (Page.IsPostBack) Page.RegisterClientScriptFile("SmartNavIncludeScript","JScript","SmartNav.js");
base.Render(output);
}
protected override void RenderChildren (HtmlTextWriter writer)
{
Page.OnFormRender (writer,ClientID);
base.RenderChildren (writer);
Page.OnFormPostRender (writer,ClientID);
}
protected override void OnInit(EventArgs e){
base.OnInit(e);
Page.RegisterViewStateHandler();
}
internal string Action{
get{
string executionFilePath = Context.Request.CurrentExecutionFilePath;
string filePath = Context.Request.FilePath;
string attr;
if (String.ReferenceEquals(executionFilePath, filePath) == true){
attr = filePath;
int lastSlash = attr.LastIndexOf('/');
if (lastSlash >= 0)
attr = attr.Substring(lastSlash + 1);
}
else{
attr = System.Web.Util.UrlUtils.MakeRelative(filePath,executionFilePath);
}
string queryString = Context.Request.QueryStringRaw;
if (queryString != null && queryString.Length > 0)
attr = String.Concat(attr, '?', queryString);
return attr;
}
}
[DefaultValue("")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[WebCategory("Behavior")]
public string Enctype{
get{
string attr = Attributes["enctype"];
if (attr != null){
return attr;
}
return null;
}
set{
Attributes["enctype"] = AttributeToString(value);
}
}
[DefaultValue("")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[WebCategory("Behavior")]
public string Method{
get{
string attr = Attributes["method"];
if (attr != null){
return attr;
}
return "post";
}
set{
Attributes["method"] = AttributeToString(value);
}
}
[DefaultValue("")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[WebCategory("Behavior")]
public string Target{
get{
string attr = Attributes["target"];
if (attr != null){
return attr;
}
return String.Empty;
}
set{
Attributes["target"] = AttributeToString(value);
}
}
[DefaultValue("")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[WebCategory("Appearance")]
public virtual string Name{
get{
string attr = Attributes["name"];
if (attr != null){
return attr;
}
return String.Empty;
}
set {
Attributes ["Name"] = value;
}
}
internal string RenderedName{
get{
string attr = Name;
if (attr.Length > 0){
return attr;
}
return UniqueID;
}
}
}
}
|
|
|
|
|