ASP.NET MVC 2 wildcard route has trouble handling spaces - asp.net-mvc-2

I've got a wildcard route mapped as below:
routes.MapRoute(
null,
"{controller}/{action}/{*category}",
new { controller = "Mall", action = "Index", category = UrlParameter.Optional }
);
This has been working fine until the category has any spaces before or after slashes " / ".
For the category ART/MUSIC, it will find the page fine.
For the category ART / MUSIC, it will give me a 404 not found.
Any help would be much appreciated!

I've just answered kind of the same question here. For completeness:
If an empty space is at the end of any section of the URL before the next slash, it throws a HttpException in the System.Web.Util.FileUtil.CheckSuspiciousPhysicalPath() method which is handled by MVC and you'll get a HTTP 404 response.
You can verify that yourself by checking the checkbox for Throw in:
Visual Studio
Debug
Exceptions
Common Language Runtime Exceptions
Generally you should not have empty spaces in your URLs. I personally format my urls, that all spaces becomes a dash (-).

Related

ZK8 Filedownload.save Cut Filenames

I use "Filedownload.save" to download files with Zk, but i have a problem.
Zk cut my filenames in some characters, for example, if the linema is "FISH#CHIPS.pdf", the file dowload as "FISH.pdf"
Anyone knows how to solve it?
UPDATE:
I have follow the instructions, and i finally see that the server response this JSON:
{"rs":[["download",["/myApp/zkau/view/z_aq5/dwnmed-3/son/FISH#CHIPS.pdf"]]],"rid":9}
And i am lost now, what do Zk with this JSON on the cliente side?
The official ZK-Bug is tracked as ZK-3809
A server side workaround is the following:
split download code such as ...
Filedownload.save("test content", "text/plain", "test#test.txt");
... into ...
AMedia media = new AMedia("test#test.txt", "txt", "text/plain", "test content");
Clients.response(new AuDownload((DeferredValue) () ->
Executions.getCurrent().getDesktop().getDownloadMediaURI(
media, "test#test.txt").replace("#", "%23")));
... allowing to encode special chars as needed.
UPDATE: ZK-3809 has been fixed and will be included in ZK version 8.5.1
The problem is that # is one of those "reserved characters" that, while valid in a URL, are treated in special ways. Look at this question for more details. My guess is that everything after the # is interpreted as a fragment on the page, and hence ignored in this case.
There are ways to fix this, for example by replacing # by %23. But doing this on the server side when calling Filedownload.save changes the filename to literally FISH%23CHIPS.pdf.
Instead, we can intercept the client side method that downloads the file when the response you showed arrives. This way, zk will still give the file its normal name, and only the download will sanitize the URL. Add this to a script tag or loaded js file:
zk.afterLoad('zk', function() {
var oldMethod = zAu.cmd0.download;
zAu.cmd0.download = function(filename) {
return oldMethod(filename.replace(new RegExp('#', 'g'), '%23'));
}
});
Then it will download the file with the complete name. You might want to take the extra time and sanitize the other reserved characters as well. Read this wiki article about "percent encoding" for the right codes.
I have also filed a support ticket with zk, I think this should be handled by the client side method out-of-the-box.

Can I add multiple servlets to a WebAppContext?

I have the following Scala code to setup a Jetty server with Scalatra.
val server = new Server(8080)
val context = new WebAppContext()
context.setResourceBase("visualization")
context.addServlet(new ServletHolder(new CallTreeServlet(dataProvider)), "/*")
context.addServlet(new ServletHolder(new DataLoadingServlet(dataProvider)), "/*")
server.setHandler(context)
My problem is that it seems to work only if I register a single servlet.
If I register more than one, like I do in the code I posted, it loads only one of them.
Is it possible to load multiple servlets? I guess it is, but I can't figure out how.
If I try to load a page from the first servlet I got this error message that references only pages belonging to the second servlet:
Requesting "GET /callTrees" on servlet "" but only have:
GET /components
POST /load
POST /searchCallTrees
POST /selectPlugIn
To troubleshoot this, you should verify the servlet lifecycle. One convenient way to do this is to peruse the servlet container's logs to see what it reports while starting up the web application. It should tell you about each web app ( servlet context ) and each servlet . . .
However, I think I see what your problem is. Your servlet path mappings are kind of funky. It looks to me that you are mapping both servlets to receive ALL requests. This can't work, from a practical point of view, and might not work in terms of the servlet rules. From the servlet specification:
SRV.11.2
Specification of Mappings
In the Web application deployment descriptor, the following syntax is used to define
mappings:
• A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used
for path mapping.
• A string beginning with a ‘*.’ prefix is used as an extension mapping.
• A string containing only the ’/’ character indicates the "default" servlet of
the application. In this case the servlet path is the request URI minus the con-
text path and the path info is null.
• All other strings are used for exact matches only.
I suggest you make them both unique. As it looks now, you have them both at "/*" which is kind of like the "default servlet", but not . . .
Why not try "/first/" and "/second/" as a sanity check. Then move from there toward getting the configuration how you like.

MVC2 Slash char in url

I want to use encrypted strings in MVC2 urls. A typical url in my app looks like this:
http://localhost:29558/Account/PasswordReset/ZKGeDMZikfIsnO8/MEs7SCBlI+MZo1Je8LM5dTEeCt3u91ARPUcavT5UXfVVRfyE
Note that everything after PasswordReset/ is the encrypted string. In the example the encrypted string contains a slash, and this is causing MVC to crash.
I've tried adding a MapRoute in Global.asax.cs as follows:
routes.MapRoute(
"PasswordResetSpecialCase", // Route name
"Account/PasswordReset/*", // URL with parameters
new { controller = "Account", action = "PasswordReset" } // Parameter defaults
);
but MVC2 is still falling over because the encrypted string contains a slash char. If I remove the slash then it works, but obviously that's no good.
How do I get MVC2 to regard everything after the PasswordReset as pure data?
Thanks.
Your maproute contains an error. Replace the * with {*nameOfParameter}

ASP.NET MVC Route parameter separate by ":" char

Now I am not sure it practical or not but I like to have a URL like this
http://example.com/field1_query:field2_query map but it seem like ASP.NET MVC Routing not happy with the ":" char here my route
routes.MapRoute("filter",
"{field1_query}:{field2_query}",
new { controller ="...", action="..."} );
It doesn't work but if I change to {field1_query}/{field2_query} it works fine (which mean my URL also change http://example.com/field1_query/field2_query).
The colon is a reserved character in a URL. See the IETF spec. You would need to escape any restricted or reserved characters.

How to route lower-case URLs ('questions/add_to_favorites/123') with underscores in ASP.NET MVC2?

ASP.NET MVC 2 controllers and actions use UpperCamelCase.
For some reasons many big sites, including SO, use lowercase (with underscore) for controllers and actions in the urls. Examples:
https://stackoverflow.com/questions
https://stackoverflow.com/users/377920/randomguy
http://www.reddit.com/ad_inq/
http://www.wired.com/special_multimedia/mobile/
etc.
I would like to know how this is accomplished.
The default router seems to be case-insensitive, ie. stackoverflow.com/questions/ask will be directed to Questions-controller's Ask() method without a problem.
However, say we want to direct questions/add_to_favorites to Questions-controller's AddToFavorites() action.
How is this accomplished?
Is it now required to use Html.ActionLink("add_to_favorites")
instead of Html.ActionLink("AddToFavorites") to make the links in the HTML point as questions/add_to_favorites instead of Questions/AddToFavorites?
Edit:
Similar posts
How can I have lowercase routes in ASP.NET MVC?
ASP.NET MVC: Get lowercase links (instead of Camel Case)
One way to support underscores is to use the ActionName attribute:
[ActionName("add_to_favorites")]
public ActionResult AddToFavorites() {
// ...
}
However, this doesn't work for controllers. Perhaps if we could somehow remove all the underscores from the request before it gets to the routing mechanism, then it would work.
You can add custom routes manually. This is not an universal solution and must be added for every controller and action separately.
routes.MapRoute(
"Web2.0 RoR style lowercase URLs with underscores",
"questions-foo/add_to_favorites",
new { controller = "Questions", action = "AddToFavorites" }
);
The cool thing is that the URL generating Html-helper methods don't need to be modified. The routing table is used to route incoming requests and to generate URLs. So,
Html.ActionLink("Add to favorites", "Questions", "AddToFavorites"); maps to /questions-foo/add_to_favorites.
Note that the original /Question/AddToFavorites still works as does /qUeStIoN/aDdtOfAvOrItEs as well as /qUeStIoNs-FOO/ADD_TO_FAVORITES because the default routing mechanism is case-insensitive.