Route ashx path to ApiController - c#

I have a legacy application where an ashx path used to go to an HttpHandler but I would like it to go to an ApiController without changing the path.
So my.application.com/auth/gettoken.ashx used to go to an "old-school" ashx.cs file, but now I want it to go to a regular WebAPI controller.
I've tried removing the handler and adding an ApiController with the correct route. This works locally, but not in production. I assume because my local IIS Express is configured differently than the production IIS.
Can I achieve this? I would be okay with disabling ashx handlers altogether. I've tried this in my web.config, but it didn't work:
<remove name="SimpleHandler"/>
I've looked into a redirect, but I'm doing a POST to this URL, so a redirect won't seem to work either.
So, can I, in any way, have a call to a path with an .ashx extension be routed to a regulare WebAPI ApiController?

I've currently reintroduced the ashx file, as I didn't find any other solution. If someone ever does, I'd happily mark that as the accepted answer (and change my code).

Related

URI in DELETE request's URI with MVC 5

We have a version control service which should be accessible through our REST API. One of those operations allows to delete a directory in SVN. Ideally, I'd like to send a DELETE request with the URI of the target to delete, something like this: http://service:4711/directory/http%3A%2F%2Fsome%2Fdirectory
What happens isn't new and there are plenty of answers out there. Unfortunately, they do not work for me. Depending on what I try, I get a 404 or a 403 (due to the malicious colon).
Let me show you some code and what I've tried without success so far:
// The action in my controller
[HttpDelete]
[Route("directory/{uri}/")]
public void DeleteDirectory(string uri)
{
var x = HttpUtility.UrlDecode(uri);
}
I am using MVC version 5.2.3.0.
I've tried:
[System.Web.Mvc.ValidateInput(false)] on the action and/or the class.
Setting runAllManagedModulesForAllRequests="true" in the web.config.
Setting requestPathInvalidCharacters="" in the web.config.
Setting requestValidationMode="true" in the web.config.
Right now, I see four possible solutions:
I've done something wrong with the previous approaches.
I have to create a custom RequestValidator.
I have to double encode the URI in the request.
Send a POST request instead of DELETE.
One may say, put it in the body of the DELETE request. But this option is highly controversial, so I'd like to ignore this one from the very beginning.
So what have I done wrong and what do you suggest to do?
Best regards,
Carsten
Colons in URI's in MVC are not allowed to be used until after the querystring '?' character in an URL, even when it is encoded as %3A.
Therefore, unless the SVN is http/s independent you could drop the initial http: from the parameter passed in an append it in the code.

Directory in MVC3 Project

I have a "Tools" area of the MVC3 site I'm currently working on. One of the tools I'm integrating on the site I need to run in a virtual directory. Setting up a virtual directory under the /Tools folder works fine for the app itself, but for navigation to /Tools/, I'm getting "Directory listing not allowed". How do I tell IIS to let MVC routes handle this URL?
We'll be using IIS6 in production, so it's important for it to work with that.
Thanks in advance.
EDIT: For clarity, here's the setup:
/Tools/RoutedTool1
/Tools/ToolInVirtualDirectory
/Tools/RoutedTool2
/Tools/
The routes for the routed tools work fine, but since I had to create a directory under the root to setup the "ToolInVirtualDirectory", IIS is hijacking the "/Tools/" request and trying to send it to the directory, ignoring the route.
You should set routes.RouteExistingFiles = true in Global.asax.cs.
Remember that since this property plays at global level you have to ignore the css files and other stuff you don't need to handle by the routing infrstructure before setting this. For more idea please refer this post.
In your RegisterRoutes section in Global.asax, you add ignore routes that the routing system ignores. There should already be an example for .axd's in the config.

Why does DotNetNuke log me out on post ajax requests?

Previously, when I tried to do an ajax call to an ashx as a non-superuser account (i.e. as portal specific user) my web server would return cookies to clear my authorization. I posted a question about this and it seemed the answer was to make sure that the portalid=xx was specified in my GET parameters.
However, I have just found out that if I add portalid=xx in a POST request, DotNetNuke seems to ignore and and log out any non-superuser account.
How can I keep authorization during DNN POST ajax requests?
I think I have a good handle on the whole situation, and unfortunately it appears that the only true solution is to make sure each child portal has its own subdomain rather than a sub-url (e.g. portal.domain.com rather than domain.com/portal).
The problem is that when your portal 0 is domain.com but portal 1 is domain.com/portal everything works correctly until you need to access an .ashx file via ajax. What happens then is the URL that's requested is instead domain.com/DesktopModules/MyModule/Handler.ashx, which does not contain the /portal/ in it, thus causing DNN to think you are doing a request on portal 0 and logging you out.
While GET requests can overcome this with a portal=1 parameter, this does not seem to work for POST requests.
Therefore, the best solution it seems is to have your portal on a distinct subdomain (portal.domain.com), and then you don't risk missing something like this.
I've found a few things for you to check out and see if any of them solve your problem.
Make sure you are using a ScriptManagerProxy. This allows ascx pages to use AJAX while the parent page is also using AJAX.
There have been many reports of people not being able to run AJAX with DNN if Page State Persistence is set to "Memory". Those who experience this have been able to fix it by switching Page State Persistence to "Page". The easiest way to do this is to run this query:
update HostSettings
set SettingValue='P'
where SettingName='PageStatePersister'
After you run that, you'll need to recycle the application. If you don't have access to the server, just add a space or carriage return to your web.config file (that will force the app to recycle).
Lastly, you might see if you have this line in your web.config. Sometimes removing it will help:
<system.web>
<xhtmlConformance mode="Legacy" />
</system.web>

global.asax not being updated

We have a web application where we are using global.asax for url rewriting. We use a compiled version of the site on the live server.
As a part of modification request, we had to add some custom native AJAX code where javascript would call a webservice to update the content of the page. For being able to call the webservice with extension .asmx, we modified the url rewriting code to handle asmx requests seperately.
this arrangement works fine on the local machine, but when we publish the site and deploy it on the live server, the new code doesnt seem to get included. It still skips the condition to check the ".asmx" extension, and throws a page not found exception considering the webservice name as a page name.
We have tried looking all over and googled for such things as well.. but no avail..
any pointers on what might be going wrong.. ?
Assuming your URL rewriting is good (isn't that normally implemented as a HttpModule?) I'd check to make sure that there's an ISAPI mapping in IIS on production that sends .asmx requests to ASP.NET.
If you think your changes to the global.asax haven't been rejitted then you can always stop the application pool, go find your web applications compiled bits in c:\windows\microsoft.net\framework[version]\temporary asp.net files... and delete the jitted version. I've seen ASP.NET miss when it comes to Jitting changes before.
I'd also consider running http fiddler (IE) or tamper data (FireFox extension) on one of the pages that makes calls to the web service. It will tell you exactly how the page is calling the web service and you can validate that the called URL is correct.
There is machine.config file where you can add HttpModules. I also think that you can do that through web.config.
One reason I can think of is that in the Web.config, you might have configured the routing module in the system.web section but not in system.webServer (or at least forgot something in there).
I the similar problem before and the solution was to remove the module & add it again in the system.webServer section of the Web.config like this:
<system.webServer>
<modules>
<remove name="UrlRoutingModule" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, e="RoleManager" type="System.Web.Security.RoleManagerModule"/>
</modules>
</system.webServer>
It might be a different module or handler but the idea is basically the same. It's important to "remove" the module first.

Rewriting URLs in ASP.NET?

I am using ASP.NET C#.
How do I implement URL re-writing procedure that is similar to StackOverflow.com?
http://stackoverflow.com/questions/358630/how-to-search-date-in-sql
Also, what is the meaning of values such as "358630" in the URL? Is this the question ID (the basis for which they use to fetch the data from the table)? Whatever it is, in my application I am identifying records using an "ID" field. This field is an identity column in an SQL table. Right now, my URLs are like the following:
http://myweb.com/showdetails.aspx?id=9872
But I'd like them to appear like:
http://myweb.com/showdetails/9872/my_question_title
Or:
http://myweb.com/9872/my_question_title
Or whatever the best way, which will taste good to search bots.
My application is hosted on Go Daddy's shared hosting service, and I feel that no customized ASP.NET "HTTP module" or no customized DLL for URL re-writing is working on their server. I tried many samples but no luck yet!
I found that Stack Overflow is hosted on Go Daddy (shared hosting?). Maybe Stack Overflow's method will work for me.
SO is using ASP.NET MVC. You really need to read in details how MVC URL rewriting works, but the gist of it is that the 'questions' part in the URL is the name of the Controller class (which roughly corresponds to the 'showdetails' in your URL) and the number is a ID parameter for the default action on that Controller (same as the parameter 'id' in your URL).
Since MVC isn't an option you can try redirecting the 404s. This will work in ASP.NET 1.1 and above: Redirect 404s and 405s to your own handler using either IIS config or web.config, parse out the request in the handler and redirect to the appropriate resource.
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="error.html">
<error statusCode="404" redirect="newHandler.aspx"/>
</customErrors>
</system.web>
</configuration>
Before the advent of System.Web.Routing, the common practice was to use UrlRewriter.NET. Worked well enough, but could bite you when configuring IIS. I'm not sure if there are any simple ways of using the new Routing classes in ASP.NET (i.e., drop it in and go vs. refactoring code).
please explain the meaning of values
such as "358630" in the URL
That is (presumably) the ID for the question in the database. In the MVC model
myurl.com/questions/358630
is analogous to
myurl.com/questions.aspx?id=358630
The question title on the end of the URL is actually being ignored by the app. It's generally "tacked on" for search engine optimization and human readability purposes. In fact, you can change the title of this question in the URL and notice the page still loads just fine.
The new System.Web.Routing dll is part of ASP.NET 3.5 SP1, and is bin deployable on ASP.NET 3.5, so you could use the features of that on a classic ASP.NET WebForms site.
You'll probably want to take note of Phil Haack's comments in his post on using MVC on IIS 6 as you'll probably need to include the .aspx extension in your routed urls
http://www.mysite.com/controler.aspx/action/id
You might also want to check out Questions Tagged SEO.
The ignored question name at the end of the url is often called a "Slug", and is used for SEO purposes to include the page title in the url.

Categories