MVC - Can I expose action methods with URL extensions? - asp.net

How can I do the following?
I want a user to browse to https://localhost/Registration/GetCaptchaAudioInternetExplorer.wav and have it run the action of GetCaptchaAudioInternetExplorer on the Registration controller, which serves an audio/wav file.
What works for me right now is browsing to https://localhost/Registration/GetCaptchaAudioInternetExplorer
But what do I need to do to make https://localhost/Registration/GetCaptchaAudioInternetExplorer.wav route to the same action? Is there a way in MVC to specify action routes for something like this?

You can use URL Rewrite for IIS (7+) to do this, basically:
<rule name="Rewrite Wav Files" stopProcessing="true">
<match url="^Registration/?(.*)\.wav$" />
<action type="Rewrite" url="/Registration/{R:1}" />
</rule>
That will strip off the extension and send it to the controller. It's rewritten so it should still present as Registration/GetCaptchaAudioInternetExplorer.wav in the browser.
Potentially you can try setting relaxedUrlToFileSystemMapping:
<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true" />
But with .wav being a real thing, I'm not sure if that will work. More detail on Haacked.
A final alternative you can enable RAMMFAR:
RAMMFAR means "runAllManagedModulesForAllRequests" and refers to this
optional setting in your web.config.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
That should send all requests through MVC regardless of extension. I say final, as this has a performance hit.

A little bit of a spinoff, but I was able to instead get https://localhost/Registration/GetCaptchaAudioInternetExplorer/clip.wav routing to my GetCaptchaAudioInternetExplorer action.
Two simple changes:
1) Add this route to your action:
[Route("clip.wav")]
public async Task<ActionResult> GetCaptchaAudioInternetExplorer()
2) Add this handler into your web.config:
<system.webServer><handlers><add name="Wave File Handler" path="clip.wav" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Related

Error 400 Bad Request - individual redirect

The Seo Company ask for making redirect each 404 bad request to specific url.
I asked for redirect an error 400 (Bad request) to special page.
I can do it in the web.config file, but the requirement is each url to special page
for example
https://stackoverflow.com/questions/askhttps://stackoverflow.com/questions/ask =>(301) https://stackoverflow.com/questions/ask
https://stackoverflow.com/questionshttps://stackoverflow.com/questions => (301) https://stackoverflow.com/questions
Is it possible?
My application is ASP.NET (Not MVC) on IIS SERVER
Thanks
Caveat:
You say this is "ASP.NET (not MVC)". I'm going to assume this means you're using WebForms rather than ASP.NET Core. The following advice can be used in both cases, but in case of ASP.NET Core only if you're hosting with IIS.
Answer:
You're looking for IIS URL Rewrite, a module that can be installed in IIS then configured via your web.config. One feature this provides is rewrite maps which are essentially a list of from and to URL mappings where a request for the former will cause a redirect to the latter. The documentation for URL Rewrite maps is here, and here's an example from the documentation:
Define your mappings:
<rewrite>
<rewriteMaps>
<rewriteMap name="StaticRewrites" defaultValue="">
<add key="/article1" value="/article.aspx?id=1&title=some-title" />
<add key="/some-title" value="/article.aspx?id=1&title=some-title" />
<add key="/post/some-title.html" value="/article.aspx?id=1&title=some-title" />
</rewriteMap>
</rewriteMaps>
</rewrite>
Then add a rewrite rule to use the mappings you just defined:
<rules>
<rule name="Rewrite Rule">
<match url=".*" />
<conditions>
<add input="{StaticRewrites:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
</rules>
In your case you'll want to use the Redirect action rather than Rewrite.
The module provides a lot of other configuration options.
On asp.net webforms set a page i.e. Redirect.aspx to redirect all the Error of type 400:
<configuration>
<system.web>
<customErrors defaultRedirect="Error.htm"
mode="RemoteOnly">
<error statusCode="400"
redirect="Redirect.aspx"/>
</customErrors>
</system.web>
then on the page see the Url it cames from by:
Request.UrlReferrer
then handle accordingly

asp.net core 2 multiple web.config files (different environments)

This issue is not related to application configurations (custom), but more to do with IIS settings.
So I need the following to be in the web.config when i create a publish for my app.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="Redirect to https" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>
</configuration>
However, when debugging i only want the part and not the http redirect (If i try to debug my app with the rewrite in the web.config it does not start)
in previous asp.net, we could have multiple web.configs for debug and release and it would transform when published.
I simply want to the all of the above code to be in the web.config when published, and only part to be in applied in web.config when i am debugging
This isn't a true answer to your question, but I've got what I think is a much better solution overall. For some time, I've found the fact that URL Rewrites have to go into the Web.config to be frustrating. As careful as you are, it's almost inevitable that you're going to overwrite the Web.config at some point, removing rewrites that have been added to it. This is especially the case if a developer doesn't know better and adds a rewrite directly through IIS, but never copies it over to the project's Web.config in source control (which happens more often than not).
As a result, I started creating a site in IIS just for redirects like this. It has nothing but a Web.config, and then I add the bindings that I'm redirecting from to it. For example, for a rewrite like this, you'd add the binding for the HTTP version of your domain to the redirect site and the HTTPS binding to the actual web application site. Then, you can create the rewrite rule on the the redirect "site", and never ever worry about accidentally overwriting it, because you never publish anything there. This would effectively side-step your issue here, entirely.

URL Rewrite rule with HTTP headers

I'm trying to use the URL Rewrite module of IIS to redirect my users to Another application/site on the IIS server, however I need to retain the custom HTTP headers included for authentication purposes, but they seem to get lost in the rewrite. Does anyone know if, and how, the rules must be setup in order to include those HTTP headers when sending the user on his/her merry way?
This is the rule, as per today:
<rewrite>
<rules>
<rule name="API Redirect">
<match url="/API/Tracker/\d{1,2}.\d{1,2}/(.*)" />
<action type="Rewrite" url="/Tracker/1.0/tracker.svc/{R:1}" appendQueryString="false" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
I was having problems with something similar. I kept losing some Cache-Control headers that I was attempting to use.
The below was able to help me out. I'm not sure how you would go about doing this if you wanted your headers to have dynamic values, but this worked for me.
I came to this while using IIS 8.5.
Go into your site, and in IIS > HTTP Response Headers
Then add the custom header that you would want to use and the value. Again, I'm not sure how you would go about doing this if you needed the header to have a dynamic value.
Have you tried to enable querystring?
appendQueryString="true"
Just wanted to share a solution that would apply a custom http header based on the current URL - not sure if this is exactly what you are looking for but it worked for me when I wanted to add a X-Robots-Tag to all requests to our admin-page.
In web.config, add this:
<location path="admin">
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Robots-Tag" />
<add name="X-Robots-Tag" value="noindex"/>
</customHeaders>
</httpProtocol>
</system.webServer>
</location>

Can I disable a asp.net web api route in web.config?

I need to disable a route temporarily in an asp.net webapi app and I cannot do compile and do another deploy.
Can I just a disable a asp.net web api route in web.config?
I don't think you can disable a specific route in web.config. Normally if you want to disable a route, you can use IgnoreRoute, or just remove the route in WebApiConfig.cs or Global.asax file wherever the route exists.
Since you only want to do it in web.config without doing compile and another deploy, I can only think about two ways.
1) Use URL Rewriting
<rewrite>
<rules>
<clear />
<rule name="diableRoute" stopProcessing="true">
<match url="api/YourWebApiController" />
<action type="Redirect" url="Error/NotFound" appendQueryString="false" />
</rule>
</rules>
</rewrite>
This result will return the 404 Error page.
2) Setting authorization rules
<location path="api/YourWebApiController">
<system.web>
<authorization>
<deny users="*"/>
</authorization>
</system.web>
</location>
This result will return to the login page, because the access to the web api route is denied.
You can customize either one to your need.

How to deal with web.config in a url search term

I am creating a search page in ASP.NET MVC3.
The url of calling the action was:
http://mydomain/Search?q=searchterm
it works fine if i search the keyword "web.config":
http://mydomain/Search?q=web.config
But now, i want the url to be:
http://mydomain/Search/searchterm
I have done this with adding the route into global.asax, but when i search "web.config", like http://mydomain/Search/web.config the server will end my request, because it thinks i am requesting the physical web.config file in the search directory.
Is there anyway to let asp.net consider the {q} in the url "search/{q}" as the parameter of the search action, not a request of a file?
In your RegisterRoutes in Global.asax you could enable requests for existing files to pass through the routing engine:
routes.RouteExistingFiles = true;
Notice that if you do that all request will now go through the ASP.NET MVC routing engine. So if you don't want to see broken images or javascript and CSS references you will need to explicitly exclude them:
routes.IgnoreRoute("scripts/{resource}.js");
routes.IgnoreRoute("content/{resource}.css");
routes.IgnoreRoute("iamges/{resource}.png");
routes.IgnoreRoute("iamges/{resource}.jpeg");
...
Also if you are hosting your application in IIS 7+ you need to remove some of the security filters that prevent you from serving web.config an .config files in general:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config"/>
</fileExtensions>
<hiddenSegments>
<remove segment="web.config"/>
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
You could use the URL Rewriter Module in IIS to do this for you; it would remove the necessary logic from Global.asax and allow you to use it across your website for simplifying the urls.
Rewriter Module
Adding a Rewriter Rule
Sample rule:
<rewrite>
<rules>
<rule name="Rewrite to search">
<match url="^search/([_0-9a-z-]+)" />
<action type="Rewrite" url="search.aspx?q={R:1}" />
</rule>
</rules>
</rewrite>

Resources