ASPX FriendlyUrls MapPageRoute generalised for all folder paths - asp.net

We are in the process of rebuilding an old web ASPX site to implement FriendlyUrls (yes, a little slow off the mark :-)).
Within Global.asax we can implement:
Routes.MapPageRoute("ItemAction", "FolderPath/{ItemKey}/{ItemAction}", "~/FolderPath/Default.aspx");
This gives ItemKey & ItemAction for a specific FolderPath - all good.
However, we have about 80 FolderPath to satisfy & more may be added later.
That would mean 80 hard coded lines of MapPageRoute().
We are looking for a way to generalise this into as few hard coded statements as possible.
We had thought of loading the Route Map into a static (perhaps XML or DB) file to load, parse & execute the MapPageRoute() in a loop. However, this still requires making sure the edit of folder paths is correct, and the web site would require a restart (its on a shared commercial host).
What we are looking for is something like either:
Routes.MapPageRoute("ItemAction", "{FolderPath}/{ItemKey}/{ItemAction}", "~/{FolderPath}/Default.aspx");
Routes.MapPageRoute("ItemAction", "*/{ItemKey}/{ItemAction}", "~/*/Default.aspx");
That way we can add new folder paths without updating anything.
As background, we have been using Web.config to achieve something like this - the current URLs look like "/FolderPath/ItemAction_ItemKey.aspx" e.g. "/FolderPath/Save_MyItem.aspx". We are looking to drop the ".aspx" and turn to more conventional, current URL formats.

Related

Replacing the Ajaxfileupload control in a Windows Forms application

We have a windows forms legacy asp.net site that uses the AjaxFileUpload control to manage file uploads. One of our issues is that we have different file type uploads but these types are distinguished not by the extension, but by an element right before the extnsion, EG: .gh.zip vs. .gy.zip. It seems that if I add one of these, but not the other, to the AllowedFileTypes, it doesn't allow either. Is it possible to piggyback some additional JS validation code to prevent an invalid file name, or would I need to replace the entire module with something else, and if so, what would be the recommendation for something that's going to be the least time-consuming that will offer a reasonable amount of configuratability?
That control is open source - you can download the source and change it if you wish.
However, why would not just specifying zip as allowed file type work?
If I set a allowed extension of zip?
Then all of these work:
.gh.zip ok
.gy.zip ok
.pdf no
However, my markup is this:
<ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server"
OnClientUploadCompleteAll="MyCompleteAll" ChunkSize="16384"
AllowedFileTypes="zip"
/>
So, above only allows zip files.
if I try to say add a pdf file to above que, then I get this:
So just add allowed extension type = zip
(Edit: do NOT include the "." in this extension)
I not sure why that would not work?
But as noted, you can grab the source - it is open source code now.
However, I suspect perhaps some other issue is going on here?
Or maybe you need "more" complex file extensions parsing?
I mean, you could for the "rare" cases or say some "out liner" cases allow that file up-load, and THEN the post-processing code could reject the file type anyway, right?
However, looking at above, just specify file type = zip, and you should be ok.

How can I change this .NET code to File.Exists?

I am working with a framework written in .NET and I do not know .NET. I just need to change this one line where it checks to see if a variable exists, and I need to change it to instead just check on the server to see if the file itself exists.
Here is what is there now:
#if (!string.IsNullOrEmpty(Model.DrawingLink2){
Is this the correct code to change it to check if the file exists instead?
#if (File.Exists(/Portfolio/#(Model.FileNumber)/Images/Large_#(Model.FileNumber)_1.jpg))
You need to map that file, relative to the root of the web application, to the physical file system. You can use HttpServerUtility.MapPath for that. You also need quotes around string literals. The process running the code also needs read access to the directory (very likely the case, just mentioning it to be complete).
#if (File.Exists(HttpServerUtility.MapPath("/Portfolio/#(Model.FileNumber)/Images/Large_#(Model.FileNumber)_1.jpg"))

Pass value WinForm =>(page.html?query123)=> HTML =>(page.aspx?query123)=> asp.net //esle?

The problem here is the middle of the line (HTML).
The chain:
I have WinForm program that uses awesomium (alternative to native webBrowser) to view Html page that has a part of asp.net page in it's iframe.
The problem:
The problem is that I need to pass value to asp.net page, it is easily achieved without middle of the chain (Html iframe) by sending hashed and crypted querystring.
How it works:
WinForm do some thing, then use few-step-crypt to code all the needed values into 1 string.
Then it should send this string to asp.net page through the iframe (and that's the problem, it is easy to receive query string in asp.net page, but firstly I need to receive it in Html and send to asp.net).
Acceptable answers:
1) Probably the most easily one - using JavaScript. I have heard it is possible to be done in that way.
How I imagine this - I send query string from WinForm to Html page as http:\\HtmlPage.html?AspNet.aspx?CryptedString
Then Html receive it with JavaScript and put querystring "AspNet.aspx?CryptedString" into iframe's "src=http:\\" resulting in "src=http:\\AspNet.aspx?CryptedString"
And then I easily get it in asp.net page.
2) Somehow create >>>VIRTUAL<<<(NOTE: Virtual, I don't want querystring to be saved on the HDD, even don't suggest) asp.net or html page with iframe source taken directly from WinForm string.
Probably that is possible with awesomium, but I'm new to it and don't know how to (if it is possible ofc).
3) Some web service with which I can communicate between asp.net and WinForm through the existing HTML iframe.
4) Another way that replace one of 3 previous, that doesn't save "values" in querystring/else on HDD nor is visible for the user, doesn't use asp.net page's server to create iframe-page on it. On HTML page's server HTML is only allowed, PhP isn't.
5) If you don't know any of 4 above - suggest free PhP hosting without ads (if such exists, what I highly doubt).
Priority:
The best one would be #3, then #2, then #1, then #5 (#4 is excluded as it is unknown).
And in the end:
Thanks in advance for your help.
P.S.Currently at work, so I'll check/try all answers later on and will report tomorrow if any suits my needs. Thanks again.
Answering my own question. I have found 2 ways that can do what I did want.
The first one:
Creating a RAM file System.IO.MemoryStream or another method (google c# create a file in ram).
The second one:
Creating a hidden+encrypted+system+custom-readable-only-by-program-crypt file somewhere in the far away folder via File.SetAttributes Method and System.IO.StreamWriter/Reader or System.IO.FileStream or System.IO.TextWriter, etc. depending on what it should be.
Once this file was used for needs delete it + delete on exit + delete on start using
if (File.Exists(path)
{
File.Delete(path);
}
(Need more reputation to post few links -_-, and I don't want to post only part of them, either all or no at all, so use google if you'll need anything from here).
If you'll need to store "Small temp file" and not for a long time use first one, if "Heavy" use second one, unless you badly need to use RAM for it.

.net/iis6 Limitations of the urlMappings in web.config for extensionless url rewriting

I'm investigating a simple url rewriting setup for iis6 / net 2.0 sites.
I've added a . wildcard mapping in IIS that points to the .net executable. I'm also using the urlMappings element in the web.config to add some rewritten urls. I've moved the config outside of the web.config so I can make changes to the list without forcing application restarts, like so:
<urlMappings configSource="config\urlMappings.config">
</urlMappings>
I'd like to allow our content management to add urls to this file so that we can have extensionless friendly urls.
<add url="~/someurl" mappedUrl="index.aspx?page=123" />
This works just fine, but I'm concerned about limitations in the number of entries that I can map in the urlMappings config. I can't seem to find any documentation on this. Has anyone found any limitations?
Thanks.
Looking inside the urlMapping
I see that the mappedUrl
are store on UrlMappingCollection
that come from ConfigurationElementCollection that virtual have no limits.
The number of urls.
I think that virtual there is no limit on how many you can load.
The load time
The load delay is only on the stating the web, then its keep on a static value, and reloaded only when you change the web.config, or restart the app.
The Memory
Well you have a static collection with all that data called on the start of every request. Depends how many data you going to load on web.config.
The search time
The search time, from my research is not done using any hash method, but they compare the strings together one by one, so here maybe we have a small issue.
This is the code with the heavy search for every url
internal string HttpResolveMapping(string path)
{
string mappedUrl = null;
string str2 = UrlPath.MakeVirtualPathAppRelative(path);
UrlMapping mapping = this.UrlMappings[str2];
if (mapping != null)
{
mappedUrl = mapping.MappedUrl;
}
return mappedUrl;
}
here the UrlMapping mapping = this.UrlMappings[str2]; is calling the
protected internal ConfigurationElement BaseGet(object key)
{
foreach (Entry entry in this._items)
{
if ((entry._entryType != EntryType.Removed) && this.CompareKeys(key, entry.GetKey(this)))
{
return entry._value;
}
}
return null;
}
I need to check it a little more, but I think there is an issue on search for the url mapping.
In Real Life
Recently I optimize similar code for database calling. I get down the speed from 500ms to 150ms-200ms on a similar loop that is called 20.000-50.000 times in few seconds.
In your case I do not think that this routing is going to called more than 100-200 times in a page call. (and I say 100 because you redirect all call to asp.net, even the images)
So I think that is really depend for how super fast you won your web to be, but the users of you I do not think that they note the different, and on this point you only going to gain 10-20-30ms faster - and we speak only if you have huge amount of urls (maybe more than 1500 urls).
Also the first page with the content is called, then search from this loop, return the page, then the images follows, so the user is going to see the different only on the first 1-5 calls delay of the page and did not understand the small delay on the images.
The optimization here is only going to be measured on programs and not be understand by the users.
The times here is from my experience on my (slow) computers and is to give only the sense of my experience.
Some more words
I think that urlMapping is a ready to go solution that can help anyone to start with, but if some have the time the knowlege and the resource is worth to fix his own url mapping, make it in his needs and super fast if hes like. For start is good to have urlMapping but if you need some more advanced thinks, then you can update it later when your project go bigger.
I am fan of the speed, every second that wait on the computer is a second from our life.
How ever if it easy for you to use the urlMapping just do it, make the site workable, and then you check it again after some months.

stupid caching in asp.net

i use such code
string.Format("<img src='{0}'><br>", u.Avatar);
u.Avatar-it's like '/img/path/pic.jpg'
but in this site i can upload new image instead old pic.jpg. so picture new, but name is old. and browser show OLD picture (cache). if i put random number like /img/path/pic.jpg?123 then works fine, but i need it only ufter upload, not always. how can i solve this?
string imgUrl = _
string.Format("<img src='{0}?{1}'><br>", _
u.Avatar, _
FunctionThatLookupFileSystemForItsLastModified(u.Avatar).Ticks.ToString());
Instead of linking to the images directly, consider setting up a generic HTTP handler to serve the images.
MSDN: HTTP Handlers and HTTP Modules Overview
Stack Overflow: How to use output caching on .ashx handler
Append DateTime.Now.Ticks to the image url:
string imgUrl =
string.Format("<img src='{0}?{1}'><br>", u.Avatar,DateTime.Now.Ticks);
EDIT: I don' think this best practice are even a practice I would use. This is just a suggestion given the limited information given in case the Random implementation isn't truly Random.
Read your post again,,, sorry for general answer.
To workaround it do following
On Application_Start create a Dictionary with uploaded images save it on Application object, set it to null. Once you upload an image add it to this Dictionary. Wrap every place avatars appear on your website with function that evaluates image in Dictionary if found return imagename.jpg?randomnumber and then delete it from a Dictionary else return just an imagename.jpg.
This is going to be heavy because you will need to check each image in Dictionary but this will do exactly what you need.
You can set cache dependancy using the System.Web.Caching.CacheDependency namespace.
This can set the dependancy on the file uploaded, and will release the cache for that file automatically when the file changes.
There are lots of articles and stuff on MSDN and other places so I will not go into details on all that level of detail.
You can do inserts, deletes and other management of cache using the tools available.
(and this does not require you to change the file names or tack on stuff - it knows by the file system that the file changed)

Resources