I have a SUPER simple Web API. It is openly non-secure and simply provides free data. I'd like to move it from my personal server to shared hosting (e.g.: GoDaddy), but I'm having issues.
There are a lot of similar questions relating to 404 status when attempting to access Attribute Routing Web API services on shared hosting solutions. But none of them have worked for me. This is my SUPER Simple current setup:
Create a new .Net Framework 4.5 EMPTY C# Web Application named YourApplicationName
Ensure all checkboxes and packages are NOT Checked
Add a New "Global.asax" object
Replace the entire contents of the C# with the following:
using System.Web.Http;
namespace YourApplicationName
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start()
{
System.Web.Mvc.AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure((HttpConfiguration config) => { config.MapHttpAttributeRoutes(); });
}
}
public class TestController : System.Web.Http.ApiController
{
[System.Web.Http.Route("api/Test")]
public string Get()
{
return "Test Info";
}
}
}
Replace the Web.config file with the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</configuration>
Delete ALL References other than System and System.Web
PM> Install the following two packages:
Install-Package Microsoft.AspNet.Mvc
Install-Package Microsoft.AspNet.WebApi.WebHost
With that, I can run in Dev, publish to my personal IIS, run on my company's IIS Servers, or even publish to azure (http://suamereapi.azurewebsites.net/api/Test) and if I navigate to the route, I appropriately get back "Test Info".
But when I publish to my shared hosting, I receive a 404 status. Note that mvc controllers that return Views work just fine in the shared hosting, just not the ApiControllers.
Possible Issue 1 is that the IIS pipeline is not set up as Integrated on the hosted account. Of course I have checked that mine is set to Integrated.
Possible Issue 2: Moreso related to API's NOT using Attribute Routing, is that the Register Routes needs to come before the GlobalConfiguration. This is not applicable in a pure Attribute-Routing Web API setup.
Possible Issue 3: Some of the DLL's aren't in the shared hosting GAC, and also are not published from your local setup because they are not Copy Local. I have altered Copy-Local to multiple setups from none, to just what is required, to all references.
Possible Issue 4: Shared hosting messes with the configuration paths because of virtual directories for subdomains or what not. That is fixed by adding a rewrite to the Web.config as such:
rewrite>
<rules>
<rule name="Remove Virtual Directory">
<match url=".*" />
<action type="Rewrite" url="{R:0}" />
</rule>
</rules>
</rewrite>
Possible Issue 5: Some say to fix the issue you need to add runAllManagedModulesForAllRequests="true" and work with the httpHandlers to remove and manually add extension handlers, and UrlRoutingModules.
I have done all combinations of these workarounds, but I can't imagine what the true issue is. Please let me know what I might be missing, I've spent days on this.
Related
C#, .NetCore 2.2, Visual Studio 2019
I am having a really hard time getting used to the web.config to appsettings.json conversion process. Yes, I have read the docs but there is something I am missing.
I have been told that there is no 1:1 conversion from web.config to appsettings.json. I have read that there is nothing particularly special about the appsettings.json file and that the info there could be in nearly any other format / storage system. I have read that appsettings is just read by whatever policy provider needs to read it.
How do you know what policy providers exist or which one(s) you need?
In ny current case I have an existing, older project that uses a third party web base authentication service called "Siteminder". The use case is very simple: the older app has a small set of controllers. Siteminder is configured (server level not app level) to monitor request URLs. If a request goes to "https://thing.company.com/Auth/" then Siteminder looks for its auth token and either interrupts the request and challenges the visitor for credentials or validates and passes the request on.
My new app should work the same way.
The old app has a web.config that looks something like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*"
modules="AspNetCoreModuleV2"
resourceType="Unspecified" />
<add name="handler-wa-32" path="*" verb="*"
modules="IsapiModule"
scriptProcessor="C:\Program Files\CA\webagent\win32\bin\ISAPI6WebAgent.dll"
resourceType="Unspecified"
requireAccess="None" preCondition="classicMode,bitness32" />
<add name="CASiteMinderWebAgentHandler-fcc-32"
path="*.fcc" verb="*"
modules="CASiteMinderWebagentModule-32"
resourceType="Unspecified"
preCondition="integratedMode,bitness32" />
<!-- 10 additional, similar "CASiteMinderWebAgentHandler-???-??" handlers !-->
</handlers>
<modules>
<add name="CASiteMinderWebagentModule"
preCondition="integratedMode,bitness64" />
<add name="CASiteMinderWebagentModule-32"
preCondition="integratedMode,bitness32" />
</modules>
<isapiFilters>
<filter name="SiteMinder Agent"
path="C:\Program Files\CA\webagent\win64\bin\ISAPI6WebAgent.dll" enabled="true"
preCondition="classicMode,bitness64" />
<filter name="SiteMinder Agent-32"
path="C:\Program Files\CA\webagent\win32\bin\ISAPI6WebAgent.dll" enabled="true"
preCondition="classicMode,bitness32" />
</isapiFilters>
</system.webServer>
</location>
</configuration>
I have not found Siteminder docs on using .Net Core 2.x yet. I have no idea how to let my app, the web server, whatever, know about these settingS.
It feels like there is a missing section of documentation. How do you port this sort of config over to appsettings and let whatever systems, services, providers know about them?
SiteMinder does not provide plugins for .Net Core. Further, HTTP Modules written for IIS/.Net 4.x are not compatible with .Net Core anyway, which has a very different request processing pipeline.
I've done a fair amount of work with enabling "traditional" access managers to work with .Net Core. Its tricky. (disclaimer, shameless plug here...). My company's product provides a universal REST-based interface for use with SSO products including SiteMinder, and provides .Net and .Net Core libraries (as well as Java, C, C++, and a variety of web and app servers). You might ask your SiteMinder owners to take a look, the link is on my profile.
Looks like my best solution is to continue to use web.config for Siteminder. It works. I was hoping that there was a way around that though.
Not sure what happened my project but when I tried to run it I got the error message Could not load file or assembly 'Exceptionless.Mvc' or one of its dependencies
Eceptionless.MVC is not used or referenced anywhere in my project I cant even find any text with Exceptionless......
So I used Nuget Manager to install the exceptionless.MVC package.
Now I get the error
`HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Config Error
There is a duplicate 'exceptionless' section defined `
The install of exceptionless.Mvc added the following to my web config
<section name="exceptionless" type="Exceptionless.ExceptionlessSection, Exceptionless" />
<exceptionless apiKey="API_KEY_HERE" />
<modules runAllManagedModulesForAllRequests="true">
<add name="ExceptionlessModule" type="Exceptionless.Mvc.ExceptionlessModule, Exceptionless.Mvc" />
</modules>
and the packages config was updated
<package id="Exceptionless" version="4.2.1982" targetFramework="net45" />
That is the only ref to exceptionsless/exceptionlessMVC in my project.
I am at a loss to what its look for with mvc exceptionless or where the duplicate sections are??
any help pls?
Issue was to do with a duplicate web config file stored in the IIS. Renaming that web config allowed the original to take priority removing any duplicate issues with exceptionless.
You should try removing the handler then adding it back in. Here is a similar example:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
You may need to comment out this part too.
<section name="exceptionless"....
Web.config is inheriting from Web.config from parent application. Also there is machine-wide web.config and machine.config.
1) If you application is on IIS and there is a parent application, check web.config of parent application
2) Check your machine-wide web.config and machine.config.
Assuming you're on .NET 4.0 and higher they're here:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config
(for x32 bit application pool)
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config
(for x64 bit application pool)
I searched previous questions, first, but could not find anything that solved my issue. I have a Web App project that works fine locally, then fails with 500 after having been published. This is my first time using any of the Microsoft stack (C#, ASP.NET MVC, Azure), so bear with me.
Visual Studio 2015 Community
.NET 4.5 / ASP.NET 5 Web App project
StackExchange.Redis / Fleck / React.AspNET NuGet packages
I have added the following to web.config:
<system.web>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
...
<httpErrors errorMode="Detailed" />
<tracing>
<traceFailedRequests />
</tracing>
</system.webServer>
I also turned on detailed error messages under the web app's settings using the Server Explorer view in Visual Studio (right-click the app's name, click settings). I also attempted to remotely debug the web app, but received an "access is denied"("Remote debugging does not work in Express editions of Visual Studio" maybe?). So, I'll post the web.config from the Azure web app.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<customErrors mode="Off"></customErrors>
</system.web>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpErrors errorMode="Detailed" />
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
<tracing>
<traceFailedRequests />
</tracing>
</system.webServer>
</configuration>
One or a combination of these changes mentioned above worked in providing a more useful error screen.
If someone can come along and post an answer as to which step(s) it may have been and why, etc. I'd be glad to accept it. I don't want to post an answer, as I honestly don't know which 'fixed' it.
Yes, the customErrors element belongs under system.web
The most common error people make when first deploying to Azure or any other server is to properly set connection strings for that environment, so I would start by checking those.
You mention ASP.NET 5 Web App project so this means you have a Startup.cs file, right?
Check in your project.json file if you have (if not add it) the Microsoft.AspNet.Diagnostics package.
Then add on the public void Configure handler:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
//other app.Uses
}
This is intended for local dev because it will show the detailed full error, you might want to later add it in an if:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
Source: docs.asp.net
I have MVC Web API that have POST and PUT functions; POST function calls succeeded but PUT function call failed with:
internal server error;
Functions are identical "I use one function at a time and the other one will be commented; Just for testing purposes".
public HttpResponseMessage Put(string id)
{
HttpStatusCode statusCode = HttpStatusCode.OK;
return Request.CreateResponse<string>(statusCode, id);
}
public HttpResponseMessage Post(string id)
{
HttpStatusCode statusCode = HttpStatusCode.OK;
return Request.CreateResponse<string>(statusCode, id);
}
Edit: It works fine locally at my machine for both POST and PUT (Windows 8.1); but when i move it to another machine (Windows Server 2012 )only POST functions works.
Use POST to create resources when you do not know the resource identifier. With POST creates, it is best practice to return the status of “201 Created” and the location of the newly created resource, since its location was unknown at the time of submission. This allows the client to access the new resource later if they need to
Finally i found a solution for this issue, it seems that there is an issue in WebDav, in some cases it is not enough to remove it from your application Web.Config you should disable it from IIS by following steps from this article How to disable WEBDAV in IIS
I will update this answer when i found exactly what is the problem with WebDav that make removing it from application Web.Config not enough for windows 2012 but working fine in windows 8.1
I had the same problem. PUT and DELETE endpoints worked while I was debugging in visual studio, but not when I deployed to IIS.
I had already added this
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
in my web.config, so I wasn't thinking about the WebDav. Ebraheem's answer had me looking closer at the WebDav.
Ended up that the IIS Server had WebDav Publishing enabled in Features and Roles. So I removed it and now everything works as expected.
The remove <remove name="WebDAVModule" /> is not enough. What I found out is that you have to specifically remove it from handlers as well and also just to make sure the verbs are allowed you can set them in the security node. The following is what I set in my web.config which allowed the put and delete to work without setting anything in IIS.
<!-- After the <system.web> node -->
<system.webServer>
<handlers>
<!-- default handler settings here if any -->
<!-- Add the following to remove WebDAV handler -->
<remove name="WebDAV" />
</handlers>
<modules runAllManagedModulesForAllRequests="false">
<!-- Add the following to remove WebDAV module -->
<remove name="WebDAVModule" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
<security>
<!-- Add the following to specifically allow the GET,POST,DELETE and PUT verbs -->
<requestFiltering>
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="DELETE" allowed="true" />
<add verb="PUT" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
I've installed ServiceStack.Host.MVC into an existing MVC3 project that has a lot of controllers.
It's now routing to default.htm. I found another StackOverFlow question that said to change the Default redirect path, do the following.
SetConfig(new EndpointHostConfig {DefaultRedirectPath = "/Foo" });
But I really want to change it to execute the default Controller and Action as setup in the global.ascx. I've edited the DefaultRedirectPath to point at /Home, and it seems to work fine, and doesn't add Home to my url or anything, but I'm not 100% on the relationship between having an AppHost in my application.
If changing this isn't the right thing to do, what's the best way to get started integrating some Service Stack AppHost in with a regular MVC application. I'm going to move my base controllers to ServiceStackController, and slowly start using the new Session and User management stuff. Eventually, I'm going to want to use the authorization or shared sessionId with some services, but I'll get to that later.
To start, my goal is to start using some of the IOC functionality of Funq.
You probably don't need DefaultRedirectPath, because it is just a redirect to a predefined URL. You need to have your MVC controllers hit when using your old urls, and have a new URL area for ServiceStack. To do this, start by setting ServiceStackHandlerFactoryPath. It should allow you to host ServiceStack in a sub-url, and it will not interfere with your existing controllers, unless there is a conflict in the path:
SetConfig(new EndpointHostConfig { ServiceStackHandlerFactoryPath = "api" });
The ServiceStack http handler in your web.config will need to match:
<location path="api">
<!-- Required for IIS 7.0 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
</system.webServer>
</location>
The ServiceStack BootstrapAPI application sets the CatchAllController to be the HomeController of the MVC application. This worked for me.
In the AppHost::Configure, I put the following code:
public override void Configure(Funq.Container container)
{
// Other Configuration constructs here
ServiceStackController.CatchAllController = reqCtx => container.TryResolve<HomeController>();
}