-
11 May 2009 8:42 AM #1
Ext.Direct .NET Router
Ext.Direct .NET Router
Here's my implementation of a .NET router. After seeing some of the others I've modified my original implementation a bit.
Attached is both the source for the router and a small sample project to demonstrate the functionality.
http://extjs.com/playpen/router/Router-1.0.zip
UPDATED ON 24th FEB
1. Setting up the Api Handler
The API describes which methods are made available to the client. In the .NET version, this is implemented as an ASHX handler. The handler instances a provider object and passes in
a) The name of the provider
b) The url of the handler for this provider
c) An assembly containing the methods for this provider
Upon calling the configure method, reflection is used to find all classes with a DirectActionAttribute. From here, any methods marked with either a DirectMethodAttribute or a DirectFormMethodAttribute will be included in the generated API. A simple caching class has been provided. It is recommended you use this to save generating the API on each call to the handler.
2. The rest
Simply setup your handler ASHX, in this case I've called it DirectHandler.ashx. From here, all we need to do is pass the appropriate provider and the HttpRequest to our processor and it will return a result.
NB: Any form methods will only be passed a single parameter, which is the HttpRequest object. Any other parameters are ignored.
Comments/questions/improvements welcome.Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
11 May 2009 9:17 AM #2
Cool! I just gave it a short look... A few more nice ideas! Since I have followed the last .net thread, I am working on a similar implementation too! So I am counting 3 yet...
I have just started an Open Source Project and commited the code from "shibubh" with a small change in the router it self today... What do you think about merging our ideas together?
Two things i got on my list for the shibubh's current Implementation:
- Pack things to a Dll so you dont need to add those aspx files to an existing Project
http://msdn.microsoft.com/en-us/libr...ssrequest.aspx
(makes it possible to add the proxy and router handler via web.config)
- Use JSON.NET for de- and -serialization see: http://www.codeplex.com/Json
Thinking about restrict to the use of Static classes or even support them. (This is importent cause of performance issues in big applications)
So As i have Seen so far your version solves the second point nicely... But what do you think about the first one?
regards
-
11 May 2009 11:11 AM #3
This is great! Thanks so much, Evan.
Eugene
Ext.Direct for ASP.NET MVC
-
11 May 2009 4:08 PM #4
RE:
1) You need to do some configuration to get this working, for example, passing in the assembly. I guess you could do that with a config file, however my .NET is rather rusty.
Would you have me include the core stuff in the Ext.Direct dll and then have the user extend the ashx?
2) As you mentioned, it's using JSON.NET internally.Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
11 May 2009 7:40 PM #5
hi evant,
thanks for sharing. Cool stuff. i just loved it. i love the you way code it.Shibu Bhattarai
Use JavaScript beautifier to beautify you code http://jsbeautifier.org/
Code Conventions http://javascript.crockford.com/code.html
ExtJS Core Manual http://extjs.com/products/extcore/manual/
-
13 May 2009 8:58 PM #6
good work, good idea
this is something like ajaxpro,but it's better then ajaxpro.
we can paste the client extjs and the server side c# method with it.
-
14 May 2009 5:37 AM #7
Modofications
Modofications
That was great!
But the issue is if you have tons of pages in one assembly that need lots of Ajax function for different purposes, it renders all methods to every page while it might not be needed, so I made some modification (in sample application not Library), hope that helps:
Instead of including ApiHandler.ashx as a script block, I used it as a helper class like this:
public static void Register(Page page) {
DirectProviderCache cache = DirectProviderCache.GetInstance();
DirectProvider provider;
string hash = GetHashKey(page);
string key = "Ext.app.REMOTING_API." + hash;
//After being configured, the provider should be cached.
if (!cache.ContainsKey(key)) {
provider = new DirectProvider("Ext.app.REMOTING_API", "/DirectHandler.ashx?hash=" + hash);
provider.Configure(new object[] { page });
cache.Add(key, provider);
}
else {
provider = cache[key];
}
string script = provider.ToString();
page.ClientScript.RegisterClientScriptBlock(page.GetType(), "ApiHandler", script, true);
}
private static string GetHashKey(Object o) {
return o.GetType().GetHashCode().ToString();
}
The every page that needs this functionality has to call:
In the Load event.ApiHandler.Register(this);
As this register every page in different Cache key reference I needed to do an alter in Directhandler as well:
By moving these two lines:public void ProcessRequest(HttpContext context)
{
string key = "Ext.app.REMOTING_API." + context.Request.QueryString["hash"];
DirectProvider provider = DirectProviderCache.GetInstance()[key];
context.Response.ContentType = DirectHandlerContentType;
context.Response.Write(DirectProcessor.Execute(provider, context.Request));
}
Inside of Ext.onReady method in default.aspx page, every thing is ready to go to use functions that are defined in pages. So every page has access to it's own functions only, that help organizing methods.Ext.ns('Ext.app');
Ext.Direct.addProvider(Ext.app.REMOTING_API);
Note: When registering an action, it gets name of page's type, that returns 'default_aspx' instead of Default, so I had to call:
default_aspx.Echo(.....);
Alek.
PS: adding provider can be moved to Register function in helper class like this:
So in the page there is no need to register the provider, and it will be ready on load.string script = provider.ToString();
script += @"
Ext.ns('Ext.app');
Ext.Direct.addProvider(Ext.app.REMOTING_API);";
page.ClientScript.RegisterClientScriptBlock(page.GetType(), "ApiHandler", script, true);
Alek.Last edited by alekdigital; 14 May 2009 at 5:41 AM. Reason: Move addProvider ro Register Function
-
14 May 2009 7:34 AM #8
I've updated the router, new features include:
1) Native date support. Since both Ext.encode() and the native browser JSON encoders send off dates as string, the router will automatically find date arguments in the server method and attempt to convert the parameter to a date.
2) Better exception handling.
3) Added namespace option for provider.
4) Renamed a few files, tidied up the code a bit.
Can find it here: http://extjs.com/playpen/router/Router-0.2.zipEvan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
14 May 2009 9:36 AM #9
Thank you Evant!
Maybe better to add it below your first message?
-
14 May 2009 12:49 PM #10
Bug in the router
Bug in the router
Hi, Evan. Just a quick thing, there's a bug in your implementation of Direct router. A null reference exception is thrown if you call a direct method with no parameters.
The exception is thrown from DirectProvider.cs line 187.
To fix it I've replaced this piece of code with this:PHP Code:if (request.Data == null && method.Parameters > 0)
{
throw new DirectException("Parameters length does not match");
}
else if(request.Data.Length > 1 && method.IsForm) // <--- EXCEPTION IS THROWN HERE: request.Data is null
{
throw new DirectException("Form methods can only have a single parameter.");
}
else if (request.Data.Length != method.Parameters)
{
throw new DirectException("Parameters length does not match");
}
PHP Code:if (request.Data == null)
{
if (method.Parameters > 0)
{
throw new DirectException("Parameters length does not match");
}
}
else
{
if (request.Data.Length > 1 && method.IsForm)
{
throw new DirectException("Form methods can only have a single parameter.");
}
else if (request.Data.Length != method.Parameters)
{
throw new DirectException("Parameters length does not match");
}
}
Eugene
Ext.Direct for ASP.NET MVC


Reply With Quote
