404 Error when accessing Web API 2 service - c#

I have a WebAPI2 web service that works on my DEV site as well as on a local staging site, but when I push to production I get a 404 error when trying to access the same services.
Here's an example of the problem ...
// production server returns 404 Error
http://my.servername.com/AppAPI/CustomerAPI/Session/4
// local stage site works
http://localhost:100/AppAPI/CustomerAPI/Session/4
I know that there are a number of reasons why a 404 could result. Bad routes came to mind first and seem to be the source of most 404 problems that I have seen in my research. I am using WebAPI 2 Attribute routing as seen in the controller code...
public class SessionController : ApiController
{
[Route("CustomerAPI/Session/{id}")]
[HttpGet]
public string Get(int id)
{
return "value";
}
}
On IIS the site that the service is located in is set up as an "Application" (AppAPI) under another site (my_servername_com).
The site structure on IIS looks like ...
* Server
+ Application Pools
+ Sites
+ my_servername_com
+ AppAPI (application)
+ bin
- default.aspx
- global.asax
- web.config
As you can see, I have included a test page in the site; default.aspx. This page displays correctly on BOTH locations, so I know that the site is running and accessible and that at least the root url is correct. The fact that the services are accessible on the local site suggests to me that the Routes are also set up correctly.
http://localhost:100/AppAPI/default.aspx -- works
http://my.servername.com/AppAPI/default.aspx -- works
Having ruled out any coding or routing issue that I could think of, it leaves me with an environment issue of some sort. I have gone through the IIS settings on both servers and they seem the same, so I am not sure what else to look at there.
My local environment (works) ...
OS: Windows 7 Professional
IIS: IIS 7 (7.5.7600.16385)
.NET Framework : .NET 4.5 (4.5.50938)
My production environment (does not work) ...
OS: Windows Web Server 2008
IIS: IIS 7 (7.0.6000.16386)
.NET Framework: .NET 4.5 (4.5.51209)
So I am left with two possibilities I think ...
Networking issue? - I am not sure what the problem could be here. A
little outside my wheelhouse.
Some overlooked configuration?
After doing some further research I see that there are a number of issues revolving around the global.asax and WebApiConfig. As it seemed that it could be relevant I have added them here but it's important to note that this is not an MVC application.
I did not create a WebApiConfig class but created a class called "Routing.cs" that does the same thing. Which is simply to enable the attribute routing.
public class Routing
{
public static void RegisterRoutes(HttpConfiguration config)
{
// enable attribute routing
// http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
config.MapHttpAttributeRoutes();
}
}
And of course this is simply called in the global.asax.
protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configure(Routing.RegisterRoutes);
}
Any light that someone could shed would be helpful. I am about out of ideas. the next move would be to rewrite the services in ASMX ... ugghh ... I don't want to do that!
Thanks,
G

From this link:
https://weblog.west-wind.com/posts/2011/Mar/27/ASPNET-Routing-not-working-on-IIS-70
Check that you have "runAllManagedModulesForAllRequests" as true in web.config.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">

Check order of handlers in IIS:
ExtensionlessUrlHandler-Integrated-4.0 should go before StaticFile, otherwise your api call will be handled by StaticFile resulting to 404.
IIS -> Website -> Handler Mappings -> View Ordered List
You can remove StaticFile handler at all if you don't need it in your web.config:
<handlers>
<remove name="StaticFile"/>
</handlers>
There's also a similar thread here.

Related

C# Web API 2 app generates 404 on GET method when deployed to sub directory on IIS 7.5

I have a problem that's driving me nuts.
I have a basic web api written in C# / web API 2 on .net 4.5. As long as I deploy the site to the root directory of IIS 7.5, it works fine - as soon as I deploy it to a sub directory, I get 404 errors for any method requests.
my setup is this:
I have a single controller called ServicesController with the following methods:
public IEnumerable<Service> GetAllServices()
{
return Services;
}
public IHttpActionResult GetService(int id)
{
var Service = Services.FirstOrDefault((p) => p.Id == id);
if (Service == null)
{
return NotFound();
}
return Ok(Service);
}
}
}
I have a routing template set like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
if I check the request in fiddler as it's coming through, on the root directory (root directory being localhost, or wwwroot) the request looks right:
api/services/1 (for example)
In the sub directory (called ServicesApp), the request prepends the directory name, which (I think?) may be the problem (or not), like this:
ServicesApp/api/services/1
Is there something I need to change in my visual studio project settings to modify the base call, or could it be something else? I'm a bit of a web api 2 novice, so I'm sure it's something small I'm missing.
Other things I've tried based on other posts I've read here:
-iis integrated mode is enabled in my web.config
-i did try adding runAllManagedModulesForAllRequests option in web.config as well
I can create a sub application in IIS and define the sub directory as the root, and it'll work fine, but that's not a viable option since this is going to be deployed to a remote / shared windows host that doesn't allow that level of functionality.
Any help greatly appreciated. Apologies in advance if I missed an obvious answer while searching.
Once you move your app to a subfolder, do you have a different app in the root then? web.config files inherit settings from parents apps, so if your parent is defining a setting and you place a child app which defines the same setting you might get an error (depends on which setting).
Also in IIS do you right click on the child app and select "Convert to Application"? Every application and "Child" application needs to be setup in IIS using either "Add an Application" or "Convert to Application".
Maybe you need to speak with the owner of the remote/shared windows host to find out how to do this through them. They might require another subscription for every app.
Also what path shows up when in IIS you select the webapi app folder and then click "Browse" it should open a browser with the right path in it to the root of the app.

ASP.Net MVC returns 404 for URLs with Action parameters but not for default route

I am using a WebForms application with some MVC components added in. The idea is to move more and more of the app over to MVC but there is no way it can be transitioned all at once. For various reasons I cannot control it must use ASP.Net 2.0 and MVC 2.0 since those are what ship built-in. I must also support IIS 6 and IIS 7.
First, I am well aware of the problems with extensionless routing and I am not attempting to use it so there are no issues with wildcard mappings, etc. I first attempted to use my routes ala "{controller}.aspx/{action}/{id}" but after banging my head on the wall I switched to "{controller}.mvc/{action}/{id}" but am having the same issues.
Second, I cannot get this to work even in IIS 7 Integrated mode on my dev machine, let alone Classic mode or IIS 6. It all runs correctly under Cassini but once I deploy to IIS 7 the MVC components break. Since this is on my dev machine I know ASP.Net is registered with IIS correctly and I can see all the inherited HTTP handlers in the control panel (eg: ASPX maps to PageHandlerFactory).
Symptoms:
All ASPX WebForms requests work perfectly.
An MVC requests to just the controller with no action/id specified get routed to MVC and execute properly as well.
Any request to an MVC route with an action or id immediately returns a 404. It is as if IIS thinks the ".mvc" extension is part of the folder path so it ignores the HTTP handler and returns a 404.
In other words:
/app/WebForm.aspx - HTTP 200 OK, executes WebForm.aspx.cs code-behind
/app/Fancy.mvc - HTTP 200 OK, executes /Controllers/FancyController.cs, Index method
/app/Fancy.mvc/DoThingy - HTTP 404 NOT FOUND, even though FancyController has DoThingy method
Bad Solutions: I have tried things like setting runAllManagedModulesForAllRequests but not only is that bad for performance it also breaks my Web Forms as well. Even when I set it to ignore all routes with .ASPX in them they still break.
I cannot use wildcard mapping so that is no help.
Other Details:
I setup my HTTP Handler in web.config/system.WebServer. It is the first handler listed.
<add name="MvcRoutingHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Routing.UrlRoutingHandler, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" resourceType="Unspecified" />
It doesn't seem to matter what handler I specify or what options - IIS just doesn't seem to be examining any of this configuration (again because it seems to think the Fancy.mvc part of the path is a directory name, doesn't find that directory, then bails).
My routes:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.asmx/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspq/{*pathInfo}");
routes.IgnoreRoute("{resource}.svc/{*pathInfo}");
routes.MapRoute("Default",
"{controller}.mvc/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
Update: I tried using IIS 7 Classic mode; I then added a .mvc mapping in the IIS Manager pointing at the asp_net ISAPI dll and got the same result
OK just so others don't look foolish, it turns out that this was a problem with URLs... the URL was being sent to the root of the site, not the app directory. I should have checked that to begin with. I didn't think this was the problem because when I manually typed the URL into the address bar it worked on the Index but the action method required HttpPost, so it was a combination of factors that made the script and manually-entered addresses spit out the same error message.
For anyone else mixing WebForms and MVC, double and triple-check that your URLs are correct. Here is some code I am now using on the WebForms master page so my client-side JS can know where to route MVC requests:
string baseUrl = Request.Url.GetLeftPart(UriPartial.Authority);
if (baseUrl.EndsWith("/")) baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
baseUrl = baseUrl + ResolveUrl("~/");
Page.ClientScript.RegisterHiddenField("BaseUrl", baseUrl);

How to configure the web.config to allow requests of any length

I am building a site in which i would like to create a file client side from the value of a textarea element.
I have the code in place to do this, but i am getting this error
HTTP Error 404.15 - Not Found The request filtering module is
configured to deny a request where the query string is too long.
Is there a way to override this so that I am able to process requests of any size?
If not, is there a way to generate files client side without using the filesystem/active x object?
thanks
Add the following to your web.config:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxQueryString="32768"/>
</requestFiltering>
</security>
</system.webServer>
See:
http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering/requestLimits
Updated to reflect comments.
requestLimits Element for requestFiltering [IIS Settings Schema]
You may have to add the following in your web.config as well
<system.web>
<httpRuntime maxQueryStringLength="32768" maxUrlLength="65536"/>
</system.web>
See: httpRuntime Element (ASP.NET Settings Schema)
Of course the numbers (32768 and 65536) in the config settings above are just examples. You don't have to use those exact values.
In my case ( Visual Studio 2012 / IIS Express / ASP.NET MVC 4 app / .Net Framework 4.5 ) what really worked after 30 minutes of trial and error was setting the maxQueryStringLength property in the <httpRuntime> tag:
<httpRuntime targetFramework="4.5" maxQueryStringLength="10240" enable="true" />
maxQueryStringLength defaults to 2048.
More about it here:
Expanding the Range of Allowable URLs
I tried setting it in <system.webServer> as #MattVarblow suggests, but it didn't work... and this is because I'm using IIS Express (based on IIS 8) on my dev machine with Windows 8.
When I deployed my app to the production environment (Windows Server 2008 R2 with IIS 7), IE 10 started returning 404 errors in AJAX requests with long query strings. Then I thought that the problem was related to the query string and tried #MattVarblow's answer. It just worked on IIS 7. :)
If you run into this issue when running an IIS 8.5 web server you can use the following method.
First, find the "Request Filtering" module in the IIS site you are working on, then double click it...
Next, you need to right click in the white area shown below then click the context menu option called "Edit Feature Settings".
Then the last thing to do is change the "Maximum query string (Bytes)" value from 2048 to something more appropriate such as 5000 for your needs.
Something else to check: if your site is using MVC, this can happen if you added [Authorize] to your login controller class. It can't access the login method because it's not authorized so it redirects to the login method --> boom.
It will also generate error when you pass large string in ajax call parameter.
so for that alway use type post in ajax will resolve your issue 100% and no need to set the length in web.config.
// var UserId= array of 1000 userids
$.ajax({
global: false,
url: SitePath + "/User/getAussizzMembersData",
"data": { UserIds: UserId},
"type": "POST",
"dataType": "JSON"
}}
I had a similar issue trying to deploy an ASP Web Application to IIS 8. To fix it I did as Matt and Leniel suggested above. But also had to configure the Authentication setting of my site to enable Anonymous Authentication. And that Worked for me.
I had to add [AllowAnonymous] to the ActionResult functions in my login page because the user was not authenticated yet.
If your website is using authentication, but you don't have the correct authentication method set up in IIS (e.g. Basic, Forms etc..) then the browser will be getting stuck in a redirect loop. This causes the redirect url to get longer and longer until it explodes.
For someone who experiences this while running the apps from Visual Studio, while using IIS Express, first you have to locate the applicationhost.config file being used by the application. See the answer at https://stackoverflow.com/a/41553876/1849880 on how to locate the applicationhost.config file. Then, you can change the maxQueryString value as explained above.
HTTP Error 404.15 - Not Found The request filtering module is
configured to deny a request where the query string is too long.
To resolve this problem, check in the source code whether the Form tag has a property method is get/set state.
If so, the method property should be removed.

mvc routing generates iis 7.5 error forbidden

I my WebApplication I have an ASPX WebForms Page here:
~/ASPWebforms/MyFolder/Default.aspx
If I use this code:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapPageRoute(
"SomeRoute",
"Test/{reportname}",
"~/ASPWebforms/MyFolder/{reportname}.aspx"
);
and then enter this in the browser:
localhost/MySite/Test/Default
I get the desired the result: The page ~/ASPWebforms/MyFolder/Default.aspx is displayed.
But if I use the following
code
routes.MapPageRoute(
"SomeRoute",
"Test/",
"~/ASPWebforms/MyFolder/Default.aspx"
);
and try
localhost/MySite/Test
IIS 7.5 says:
HTTP Error 403.14 - Forbidden The Web server is configured to not list
the contents of this directory.
Do I do something wrong in the last piece of code?
Thx in advance!
I had something a lot like this, and from reading around it seems like it could be caused by several different things. In my case I had a route like this:
routes.MapPageRoute("signin", "signin", "~/SignIn/SignIn.aspx")
So the route path is /signin, but there is also a folder called /signin containing the .aspx page.
I got the error response
HTTP Error 403.14 - Forbidden. The Web server is configured to not list the contents of this directory.
This was fixed when I added this line to the route config:
routes.RouteExistingFiles = true;
The error message has a grain of truth in it: /signin is a directory, and the web server is configured to not list files in it. It seems that this file path takes precedence over the route unless you configure it otherwise.
Other things that I tried:
I did not need to use a different overload of MapPageRoute
I did not need to add UrlRoutingModule to the web.config under
system.webServer|Modules. It works without that.
It works without the web.config setting
<modules runAllManagedModulesForAllRequests="true">
I do have that for other reasons, but if I remove it then this fix still works.
I did install the server feature "Http Redirection" in the machine's Server Manager|Web
Server|Add Role Services dialogue but after removing it again this still works.
Reinstall .NET 4 x86 & x64 on IIS 7.5 and setup your web site .net version.
I write simple commands by default x86.
Stopping IIS:
1)iisreset /stop
Stup command(for iis by default .net stup):
2) cd %windir%\Microsoft.NET\Framework\v4.0.30319
3)aspnet_regiis.exe -i
Reset command(for iis by defalt .net change to .net 4 version):
4)aspnet_regiis.exe -iru
Starting IIS:
5)iisreset /start
Try setting up the route using one of the overloads that sets default values like so:
routes.MapPageRoute(
"SomeRoute",
"Test/{reportname}",
"~/ASPWebforms/MyFolder/{reportname}.aspx",
false,
new RouteValueDictionary(new {reportname = "Default"})
);
Not massively confident it will sort your problem but with it working with your original example it could well do.

IRouteHandler in Web Forms: Routing requests that require HttpContext.User

I'm trying to add a pretty basic route to an Asp.Net Web Forms app (running under IIS 7, integrated mode): for requests coming to http://mydomain.com/foo/ I would like to show the results of a dynamic page (http://mydomain.com/foopage.aspx).
I've created a RouteHandler that does all this and it seems to be routing correctly.
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var page = System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath("~/foo.aspx", typeof(MyApp.Web.Foo)) as MyApp.Web.Foo;
return page as IHttpHandler;
}
The problem is, inside my RouteHandler's GetHttpHandler method, all the instances of the current user (requestContext.HttpContext.User, System.Web.HttpContext.Current.User) are null. Sadly, foo.aspx needs to know what the current user is (for login controls, role stuff, etc), so rendering the page is throwing null reference exceptions. My guess is that these route handlers are firing off before Asp.Net gets the chance to wire up the HttpContext with user info. Any idea of a work-around?
PS - I realize this can be accomplished by doing a Server.Transfer in a page at http://mydomain.com/foo/default.aspx. I'd like to use routing for this sort of thing rather than having a bunch of useless folders cluttering things up.
Thanks!
See the answer to this question, very similar.
I managed to figure this one out myself.
Much like this question, my routes were working just fine when the route origin ended in .aspx (http://mydomain.com/foo-origin.aspx), but failed when they did not (http://mydomain.com/foo-origin/).
The MSDN article on setting up routing with web forms tells you to make a few changes to web config, but leaves out that you need to set runAllManagedModulesForAllRequests to true in the modules node:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</system.webServer>
</configuration>
Now it works swimmingly.

Categories

Resources