URL rewrite and kill asp.net attempt to state the implementation method _ practical skills

Source: Internet
Author: User
Tags httpcontext parent directory reflection
1, URL rewriting has been very common, but most of the URL rewrite does not support the relative path of the page, if you want to add stress to a project that you've already developed, the second is that Microsoft's URL rewrite is handled according to regular expressions, which is good, but there are drawbacks, It is not easy to navigate to a page can only have what parameters.
I think there are a few problems to be solved:
1, to solve such as pictures such as JS can not use the relative path of the file
2, to solve a page can have several parameters and which parameters are optional
Here's how to solve these problems.
Add Handler Myhttpmodule, here is a simple handler for me (I just made a simple, not considered performance, and I was writing dead a URL rewrite is rewritten without extensions)
Copy Code code as follows:

Using System;
Using System.Collections.Generic;
Using System.Web;
Using System.IO;
Using System.Text;
Namespace MyClass
{
public class Myhttpmodule:ihttpmodule
{
#region IHttpModule Members
<summary>
Free All Resources
</summary>
public void Dispose ()
{
}
<summary>
Initialize the module and make it ready for processing requests
</summary>
<param name= "Context" > a System.Web.HttpApplication that provides access to common methods, properties, and events for all application objects within the ASP.net application </param >
public void Init (HttpApplication context)
{
Context. AuthorizeRequest + = new
EventHandler (this. Basemodulerewriter_authorizerequest);
}
<summary>
Occurs when a security module has authenticated a user authorization
</summary>
<param name= "Sender" ></param>
<param name= "E" ></param>
protected virtual void Basemodulerewriter_authorizerequest (
Object sender, EventArgs e)
{
System.Web.HttpApplication app = (System.Web.HttpApplication) sender;
Rewrite (app. Request.path, app);
}
<summary>
overriding URLs
</summary>
<param name= "Requestedpath" >url virtual path </param>
<param name= "App" ></param>
protected void Rewrite (String requestedpath, System.Web.HttpApplication app)
{
List<string> qerystring;
String virtualpath;
String inputfile = Getinputfile (app. Context, out virtualpath, out qerystring);//Get real file information
if (System.IO.Path.GetExtension (inputfile) = = ". aspx")//If it is an ASPX file, then leave the overridden URL
{
App. Context.rewritepath (Requestedpath, String. Empty, String. Empty)//Here query parameters I did not deal with, that is, request.querystring information, if you take qerystring and then to process into a string
Return
}
App. Context.rewritepath (VirtualPath, String. Empty, App. Context.Request.QueryString.ToString ());//Other files use the found path
}
<summary>
Get the absolute path and virtual path and query parameters corresponding to the URL
</summary>
<param name= "Context" ></param>
<param name= "virtualpath" > virtual path </param>
<param name= "qerystring" > query parameters if NULL please fetch httpcontext.request.querystring</param>
<returns>url corresponding Absolute path </returns>
public static string Getinputfile (HttpContext context, out string virtualpath, out list<string> qerystring)
{
String Executionfilepath = context. Request.AppRelativeCurrentExecutionFilePath.Remove (0, 2);//Get the current corresponding virtual path and kill "~/"
String inputfile = context. request.physicalpath;//gets the absolute path of the current URL for
VirtualPath = context. Request.apprelativecurrentexecutionfilepath;
qerystring = null;
list<string> qerylist = new list<string> ();
if (! File.exists (Inputfile))//To determine whether a file exists, that is, a URL that is not overridden to obtain a resource using an absolute path, and so on
{
BOOL B = false;
String FileName;
string extension;
String Applicationpath = context. request.physicalapplicationpath;//access to the directory of the website
var TempPath = GetFileInfo (inputfile, out fileName, out extension);
while (!B)//Gets a valid file directory based on the directory loop
{
b = file.exists (TempPath + "\" + extension);//Determine if the file exists
if (TempPath + "\" = = Applicationpath)//If you find the root directory and haven't found it yet, then you don't need to check it out.
{
Break
}
if (!string. Isnullorwhitespace (FileName))
{
Qerylist.add (fileName);//If not present then this is the parameter such as http://localhost:4688/WebForm1/2011/(corresponds to http://localhost:4688/WebForm1.aspx?) xxx=2011)
}
TempPath = GetFileInfo (TempPath, out fileName, out extension);
}
if (b)//If found, copy the lookup path to the output or return parameter
{
Inputfile = TempPath + "\" + extension;
virtualpath = "~/" + inputfile.replace (Applicationpath, NULL);
}
if (path.getextension (extension) = ". aspx")//if ASP.net then the list is copied to the output parameter qerystring
{
qerystring = qerylist;
}
}
return inputfile;
}
<summary>
Gets whether the specified directory + file is valid
</summary>
<param name= "Inputfile" > Directory </param>
<param name= "FileName" ></param>
<param name= "extension" ></param>
<returns></returns>
private static string GetFileInfo (String inputfile, out string fileName, out string extension)
{
var TempPath = directory.getparent (inputfile). fullname;//gets the parent directory of the passed in directory
FileName = Inputfile.replace (TempPath + "\", null);//Get subdirectory name
Extension = Path.getextension (inputfile);//Get extension
if (string. Isnullorwhitespace (extension))//If the extension is null then the ASPX file is considered
{
Extension = FileName + ". aspx";
}
Else
{
Extension = fileName + extension;
}
return temppath;
}
#endregion
}
}

Because when I'm working on an ASPX page, I'm still passing in the rewritten path, and all we have is to add a class that inherits IHttpHandlerFactory.
The code is as follows:
Copy Code code as follows:

Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using System.Web;
Using System.IO;
Using System.Web.UI;
Namespace MyClass
{
public class Myhttphandlerfactory:ihttphandlerfactory
{
#region IHttpHandlerFactory Members
<summary>
Returns an instance of the class that implements the System.Web.IHttpHandler interface
</summary>
<param Name= An instance of the "context" >system.web.httpcontext class that provides internal server objects for servicing HTTP requests (such as request, Response, session, and Server) </param>
<param name= "RequestType" HTTP data transfer method (get or POST) used by the client </param>
<param name= "url" > Requested resource system.web.httprequest.rawurl</param>
<param name= "pathtranslated" > Requested Resources system.web.httprequest.physicalapplicationpath</param>
<returns> processing requests for new System.Web.IHttpHandler objects </returns>
Public IHttpHandler GetHandler (HttpContext context, string RequestType, String url, string pathtranslated)
{
List<string> qerystring;
String virtualpath;
String Inputfile =myhttpmodule.getinputfile (context, out virtualpath, out qerystring);/This is the same as there.
object[] obj = new object[] {};
dictionary<string, string> qerystringdictionary = new dictionary<string, string> ();
var receivemembers = System.Web.Compilation.BuildManager.GetCompiledType (virtualpath). GetMember ("Receiveparameters"); get all the receiveparameters members that have access to the current page (this is my own addition, the pattern that I want to make and MVC, but it may not be good)
System.Reflection.MethodInfo Receiveparameters=null;
if (qerystring!= null&&qerystring.count>0)//if found, no parameters are not reflected.
{
foreach (System.Reflection.MemberInfo receivemember in receivemembers)//Traverse all Receiveparameters members
{
if (Receivemember.membertype = = System.Reflection.MemberTypes.Method)//Because the above gets the member but we want the method all to judge under
{
System.Reflection.MethodInfo MethodInfo = Receivemember as System.Reflection.MethodInfo;
if (methodInfo!= null)
{
var parameters = Methodinfo.getparameters ();//Get all the parameters of the Receiveparameters method
int optionalcount = parameters. Count (i => i.isoptional)//Get the number of optional parameters inside the Receiveparameters parameter
BOOL b = Qerystring.count = = parameters. Length-optionalcount;
if (Qerystring.count = = parameters. Length | | b//If all parameters of the current query or receiveparameters-go to the optional query parameter equal
{
Receiveparameters = methodinfo;//Record This method
int i = 0;
obj = new Object[parameters. length];//the value of the parameter, which is used when calling Receiveparameters
for (; i < parameters. Length; i++)
{
String name = Parameters[i]. name;//gets the name of the parameter
String value = String. Empty;
if (Qerystring.count > I)//If the Receiveparameters parameter does not have an optional argument then the string to query
{
Value = Qerystring[i];
}
Obj[i] = value;//to save the string of the query to the later call Receiveparameters
Qerystringdictionary.add (name, value);//Add to custom collection
}
Break
}
}
}
}
if (receiveparameters = = null)//To determine whether it has been found, if not found in the previous search of the file information all assigned to rewrite the file information, that is, does not exist
{
VirtualPath = context. Request.path;
Inputfile = context. Request.PhysicalPath;
}
}
var temp= System.Web.UI.PageParser.GetCompiledPageInstance (virtualpath, inputfile, context);//Compile page
if (receiveparameters!= null)//The contents of this should actually be written to the releasehandler inside, but I wrote it here.
{
System.Web.UI.Page Page = (System.Web.UI.Page) temp;
Page. Init+=new EventHandler (Page_Init)//Add an event,//There is a pagebase class should be added, so that the real path information and query parameters can be put in
SSS = receiveparameters;
Sssobj = obj;
Receiveparameters.invoke (temp, obj);
}
return temp;
}
Public System.Reflection.MethodInfo sss {get; set;}
Public object[] Sssobj {get; set;}
protected void Page_Init (object sender, EventArgs e)
{
Sss. But does not conform to the programming specification (my understanding)
}
<summary>
Enable a factory to reuse an existing handler instance
</summary>
<param name= "Handler" > System.Web.IHttpHandler object to be reused </param>
public void Releasehandler (IHttpHandler handler)
{
}
#endregion
}
}
Page code is a few ways to put more
<summary>
If more than one parameter is required, add manually such as public void Receiveparameters (string name,string value), and so on, and then automatically run this method and transmit the parameter values based on the parameters after the page compiles
</summary>
<param name= "name" > Parameter name is name</param>
public void Receiveparameters (string name)
{
var temp = Request;
}

URL of the solution, in the come to see kill tried ...
I've only written out the entity state of the event and then manually fired the control's event, and it's written in the URL that resolves the code as follows:
Copy Code code as follows:

protected void Page_Init (object sender, EventArgs e)
{
Sss. Invoke (sender, sssobj);
Page page = (page) sender;
foreach (String name in page.) Request.Form.AllKeys)/Lookup Form inside all the dictionaries should actually take __eventargument hidden domain
{
Try
{
System.Web.UI.Control control = page. FindControl (page. Page.request.form[name]);//Find this control
if (Control!= null)
{
String value = page. Request.form[page.posteventsourceid];
IPostBackEventHandler IP = control as IPostBackEventHandler;
if (IP!= null)//can be converted to IPostBackEventHandler then excite it
{
Ip. RaisePostBackEvent (value);
Break
}
IPostBackDataHandler Backdatahandler = control as IPostBackDataHandler;
if (Backdatahandler!= null)//can be converted to ipostbackdatahandler the value of the __eventtarget hidden field is passed to the control and then the change event is fired
{
System.Collections.Specialized.NameValueCollection namevaluecollection=new System.Collections.Specialized.NameValueCollection ();
Namevaluecollection.add (page. Request.form[control. Clientid],page. Request.form[control. ClientID]);
Backdatahandler.loadpostdata (Control. ClientID, NameValueCollection);
Backdatahandler.raisepostdatachangedevent ();
}
}
Break
}
Catch
{
}
}
}

This simple process is over,
I hope you will help me improve the improvement, because after all, I do not know asp.net processing mechanism ...
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.