Problems with Mono, MVC, and FastCGI - c#

I have two websites that I have created with Mono.NET. Both were built exclusively using Xamarin Studio (e.g. MonoDevelop). The first is a standard Asp.NET webforms application and the second is an Asp.NET MVC application.
I have deployed the first application to my RedHat 7 server successfully. The server is running NGINX as the pass through and leverages FastCGI. The web application itself is run at the root (/var/www/html/) and thus pointing to http://[myserver].com/ kicks of the application. This all works beautiful.
My second application (the MVC one) should run as a sort of virtual directory of the root. So pointing to http://[myserver].com/admin/ should access the MVC application. This has been configured correctly on the server and when you point to http://[myserver].com/admin, it clearly attempts to start the MVC application.
My problem is that trying to access http://[myserver].com/admin, throws an application exception:
System.Web.Compilation.ParseException
Cannot find type Letters.Web.Admin.MvcApplication
Description: Error parsing a resource required to service this request. Review your source file and modify it to fix this error.
Details: Cannot find type Letters.Web.Admin.MvcApplication
Error origin: Parser
Error source file: /var/www/html/admin/Global.asax
Error source context:
Error lines: 1, 1
1: <%# Application CodeBehind="Global.asax.cs" Inherits="Letters.Web.Admin.MvcApplication" Language="C#" %>
I've been googling about this error for 2 days with no luck. I have double checked to make sure the /bin directory exists in the /admin folder (it does) and that all of the appropriate .dll files are present including the web application dll (also present). I have made sure my Global.asax has the appropriate declaration (it does ... see below)
<%# Application CodeBehind="Global.asax.cs" Inherits="Letters.Web.Admin.MvcApplication" Language="C#" %>
I have also made sure the namespace is correct in the codebehind (it is... see below)
namespace Letters.Web.Admin
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes (RouteCollection routes)
{
routes.IgnoreRoute ("{resource}.axd/{*pathInfo}");
routes.MapRoute (
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
public static void RegisterGlobalFilters (GlobalFilterCollection filters)
{
filters.Add (new HandleErrorAttribute ());
}
protected void Application_Start ()
{
AreaRegistration.RegisterAllAreas ();
RegisterGlobalFilters (GlobalFilters.Filters);
RegisterRoutes (RouteTable.Routes);
}
}
}
I cannot for the life of me figure out the issue. Everything appears to be functioning correctly. This application runs fine on my mac using Xamarin studio. I've double checked and I have the same version of mono installed on my mac as I do on the server. I'm guessing there is probably something else going on that is being obfuscated by this error but for the life of me, I can't figure out the issue. Does anyone have any ideas?

Related

Kentico v8.2.12: Why is my WebAPI Route not registered correctly (usually only on the first release)?

Summary
A Kentico 8.2 website fo which I have recently implemented a Web API service isn't registering routes on first deployment and all calls return 404. Further redeployments usually fix the issue, but I would like to fix it permanently before it is released to PROD.
What is preventing the first deployment from registering the route properly?
Background
We have a Kentico v8.2.12 website that uses Web Forms using .NET Framework v4. I have registered a Web API Controller, but it appears on the first release the route isn't registered and any calls to the service returns "404 (Not Found)".
When I first deployed to the DEV environment the Web API route wasn't registered, but upon deploying another build it magically worked. One or two other releases into the DEV environment caused similar issues, but in these instances re-deploying the same build worked.
The same issue has now occurred when released to UAT, however as the deployments are carried out by another team it will be more time-consuming to re-deploy builds and looks unprofessional. I am also wary of this occurring in PROD---which may cause the live website to be down further than necessary.
Web API Implementation
The Web API Controller is inside the CMS Website project and not a separate library.
Global.asax.cs
The Global.asax.cs file's Application_Start() method registers the route and looks similar to the below:
protected void Application_Start()
{
// Scripts Bundling here, which havs been removed for brevity
BundleTable.EnableOptimizations = false;
// Registering the API
RouteTable.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new {id = RouteParameter.Optional}
);
}
MyController.cs
My Controller looks similar to the below stored under the CMS website: CMSApp/ApiControllers/MyController.cs
[assembly: RegisterApiController(typeof(CMSApp.ApiControllers.MyController))]
namespace CMSApp.ApiControllers
{
public class MyController : ApiController
{
Channel Channel = new Channel();
[HttpPost]
public int Create()
{
Response objResponse = Channel.Instance.DoSomething();
HandleResponse(objResponse);
return objResponse.SessionHandle;
}
}
}
In the webbrowser, accessing /api/my/create returns a 404 (Not Found), but I expect it to tell me it's a POST method.
Lib versions [Edit, I have since updated the libs but issue still prevails]
Microsoft.AspNet.WebApi : v4.0.30506
Microsoft.AspNet.WebApi.Client : v4.0.30506
Microsoft.AspNet.WebApi.Core : v4.0.30506
Microsoft.AspNet.WebApi.WebHost : v4.0.30506
Question?
Why do the first deployments into an environment not work, but most further deployments work as I expect them to?
The issue was due to ASP.NET caching.
Once "MS-ApiControllerTypeCache.xml" was removed under "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files" and IIS was restarted, the controller was picked up.

Hosting an MVC6 application under default website

I have hosted many ASP.NET and MVC applications before. I was playing with MVC6 lately and tried to host an MVC6 application.
Everything works fine if I host it as a new website. When I host it as an application under the default website of IIS, it only shows an empty page. Please find the log information below
warn:
Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when
application exits. warn:
Microsoft.AspNet.DataProtection.Repositories.EphemeralXmlRepository[0]
Using an in-memory repository. Keys will not be persisted to storage. Hosting environment: Production Now listening on:
http://localhost:23000 Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNet.Hosting.Internal.HostingEngine[1]
Request starting HTTP/1.1 GET http://localhost/MVC6 info: Microsoft.AspNet.Hosting.Internal.HostingEngine[2]
Request finished in 0.0687ms 404
Note: Default website uses application pool asp.net4.5 and my MVC6 application uses it's own application pool as mentioned in http://docs.asp.net/en/latest/publishing/iis.html#iis-server-configuration
Anyone else faced similar problem like this? I want to know how to make it work under default website
Edit: This is a bug in vs2015 rc1 https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552.
There is a workaround for this bug in above link but I followed a different method because I need to host my application in more than one website without republishing.
I resolved the above problem using the Route attribute. After adding the route attribute to an action result, application works fine
public class HomeController : Controller
{
[Route("MVC6")]
[Route("")]
public IActionResult Index()
{
return View();
}
}

DNN Web API Server Error

I'm repeatedly getting an Internal Server Error 500 when trying to make a simple call to a DNN Web API controller. I do not get this error on my development machine, nor do I get it on one of our deployment servers. However, one of our other deployment servers is the problem; and I'd like to figure out why.
Consider the following, simplistic API controller in TheBestController.cs
namespace MyTestLibrary.Controllers
{
public class TheBestController : DnnApiController
{
[DnnAuthorize]
[HttpPost]
public HttpResponseMessage TestMe()
{
return Request.CreateResponse(HttpStatusCode.OK, "I'm working");
}
}
}
With this RouteMapper in RouteMapper.cs
using DotNetNuke.Web.Api;
namespace MyTestLibrary
{
public class RouteMapper : IServiceRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapHttpRoute("TheBestController", "default", "{controller}/{action}", new[] { "MyTestLibrary.Controllers" });
}
}
}
With the following AJAX call from my Javascript:
$.post("DesktopModules/MyTestLibrary/API/TheBest/TestMe", function(data) {
alert(data);
});
I have made sure that all of the correct permissions are set for the DNN application in IIS (as well as mirrored those and all other pertinent settings that are on our server that has this working). I place the compiled MyTestLibrary.dll in the bin folder of the DNN site, and I place the javascript file in the Resources/Shared/scripts folder of the DNN site. The DNN site is reading the javascript with no issues, and I am not using a module (and would not like to because I want all of my code to be easily transferrable to an MVC site).
I have also tried using the [AllowAnonymous] tag on the controller method (to no avail).
The version of DNN on all machines is 07.01.01, and the two servers are running Server 2008 R2 64bit. The dev machine is running Win 7 64 bit.
Any ideas?
To break the comments out into an answer ;)
I've seen where IIS on Windows Server 2008 can somehow corrupt a folder that a DNN website is using, and that starts to cause issues with certain web services in DNN. Two solutions that I know have worked in the past for me.
1) Setup a new site in IIS and install DNN in that folder.
or
2) Move the DNN files to a different folder on the server, point the existing IIS website to that folder, instead of the original one.
One of those two should hopefully work for most people that run into this problem.
Now, what exactly goes wrong in IIS and why can the existing folder be fix? No clue :(

Fresh Windows + VS2012 = MVC3 Problems

I just recently got a fresh install of Windows 7 on a my PC running VS2012/VS2010. I have an MVC3 project that ran just fine before I pulled it onto this PC to run. The project still compiles on this PC and I can navigate through my site while running the app in studio (2010 or 2012), but when I tried to POST from ANY form in ANY view and pass an ID by means of the URL like this:
<form id="ScriptForm" action="/MyApp/ControllerName/ActionName/#ViewBag.IDNumber" method="post">
...
</form>
...I got this error. I did some digging and playing around to try to fix this, ultimately taking these steps to try to resolve:
Actually installed ASP.NET via the Windows Components form in Control Panel
Changed the application to use IIS Express
Well, when I changed it to run under IIS Express, I started getting a different error.
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is
temporarily unavailable.
Most likely causes:
The directory or file specified does not exist on the Web server.
The URL contains a typographical error.
A custom filter or module, such as URLScan, restricts access to the file.
Things you can try:
Create the content on the Web server.
Review the browser URL.
Check the failed request tracing log and see which module is calling SetStatus. For more information, click here.
Detailed Error Information:
Module IIS Web Core
Notification MapRequestHandler
Handler StaticFile
Error Code 0x80070002
Requested URL http://localhost:51596/MyApp/ControllerName/ActionName/1
Physical Path C:\CODE\MyApp\ControllerName\ActionName\1
Logon Method Anonymous
Logon User Anonymous
Request Tracing Directory C:\Users\cbarlow\Documents\IISExpress\TraceLogFiles\MYAPP
More Information:
This error means that the file or directory does not exist on the server. Create the file or directory and try the request again.
View more information ยป
It's almost as if it is not recognizing that this is a route and is trying to resolve the URL to a physical file (like 1.html) which obviously does not exist. But why isn't it "doing the MVC thing" and using the route? I have this in my global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
And I know this is running because I can breakpoint it.
Specs:
Windows 7 | Visual Studio 2010/2012 | Microsoft MVC3 | IIS Express
I've read all these SO posts, none seem to apply in this situation or do not help (mostly, because they apply to actual aspx pages, where I am trying to load pages via controllers):
The HTTP verb POST used to access path '/' is not allowed
The HTTP verb POST used to access path is not allowed
The HTTP verb POST used to access path '/Membership/user/' is not allowed
The HTTP verb POST used to access path '/Main/[object Object]' is not allowed
The HTTP verb POST used to access path '[my path]' is not allowed
HTTP verb POST used to access path '/' is not allowed in Facebook app
Any ideas?
The problem is here (due to my lack of experience with MVC/CSHTML):
<form id="ScriptForm" action="/MyApp/ControllerName/ActionName/#ViewBag.IDNumber" method="post">
...
</form>
The MyApp used to work on my PC (I'm honestly not sure why it doesn't work now... maybe I had set something up for that name to resolve before?) but it no longer maps to anything. It DOES work on the server, but that's because there is indeed a mapping for "MyApp" in IIS. Simply changing this form to this:
<form id="ScriptForm" action="#Url.Content("~/ControllerName/ActionName/" + ViewBag.IDNumber)" method="post">
...
</form>
...does the job more elegantly and without errors.

Deploying an HttpHandler web service

I am trying to build a webservice that manipulates http requests POST and GET.
Here is a sample:
public class CodebookHttpHandler: IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod == "POST")
{
//DoHttpPostLogic();
}
else if (context.Request.HttpMethod == "GET")
{
//DoHttpGetLogic();
}
}
...
public void DoHttpPostLogic()
{
...
}
public void DoHttpGetLogic()
{
...
}
I need to deploy this but I am struggling how to start. Most online references show making a website, but really, all I want to do is respond when an HttpPost is sent. I don't know what to put in the website, just want that code to run.
Edit:
I am following this site as its exactly what I'm trying to do.
I have the website set up, I have the code for the handler in a .cs file, i have edited the web.config to add the handler for the file extension I need. Now I am at the step 3 where you tell IIS about this extension and map it to ASP.NET. Also I am using IIS 7 so interface is slightly different than the screenshots. This is the problem I have:
1) Go to website
2) Go to handler mappings
3) Go Add Script Map
4) request path - put the extension I want to handle
5) Executable- it seems i am told to set aspnet_isapi.dll here. Maybe this is incorrect?
6) Give name
7) Hit OK button:
Add Script Map
Do you want to allow this ISAPI extension? Click "Yes" to add the extension with an "Allowed" entry to the ISAPI and CGI Restrictions list or to update an existing extension entry to "Allowed" in the ISAPI and CGI Restrictions list.
Yes No Cancel
8) Hit Yes
Add Script Map
The specified module required by this handler is not in the modules list. If you are adding a script map handler mapping, the IsapiModule or the CgiModule must be in the modules list.
OK
edit 2: Have just figured out that that managed handler had something to do with handlers witten in managed code, script map was to help configuring an executable and module mapping to work with http Modules. So I should be using option 1 - Add Managed Handler.
I know what my request path is for the file extension... and I know name (can call it whatever I like), so it must be the Type field I am struggling with. In the applications folder (in IIS) so far I just have the MyHandler.cs and web.config (Of course also a file with the extension I am trying to create the handler for!)
edit3: progress
So now I have the code and the web.config set up I test to see If I can browse to the filename.CustomExtension file:
HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.
So in IIS7 I go to Handler Mappings and add it in. See this MSDN example, it is exactly what I am trying to follow
The class looks like this:
using System.Web;
namespace HandlerAttempt2
{
public class MyHandler : IHttpHandler
{
public MyHandler()
{
//TODO: Add constructor logic here
}
public void ProcessRequest(HttpContext context)
{
var objResponse = context.Response;
objResponse.Write("<html><body><h1>It just worked");
objResponse.Write("</body></html>");
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
I add the Handler in as follows:
Request path: *.whatever
Type: MyHandler (class name - this appears correct as per example!)
Name: whatever
Try to browse to the custom file again (this is in app pool as Integrated):
HTTP Error 500.21 - Internal Server Error
Handler "whatever" has a bad module "ManagedPipelineHandler" in its module list
Try to browse to the custom file again (this is in app pool as CLASSIC):
HTTP Error 404.17 - Not Found
The requested content appears to be script and will not be served by the static file handler.
Direct Questions
1) Does the website need to be in CLASSIC or INTEGRATED mode? I don't find any reference of this in the online material, whether it should be either.
2) Do I have to compile the MyHandler.cs to a .dll, or can I just leave it as .cs? Does it need to be in a bin folder, or just anywhere in root?
RE your questions:
I don't know the answer to the first one (CLASSIC or INTEGRATED); but I can help with the second...
Yes you'll need to compile it first. I have never tried deploying dll's to anywhere other than the bin, given that that's the standard I would be suspect in putting them anywhere else even if it did work.
The way I deploy HttpHandlers is quiet straight forward - all the hard work's done in web.config, I'v enever had to go into IIS to change any settings.
For a start, for the http request to be handled by ASP.NET you need to use a request suffix that's already piped to ASP.NET - like .aspx or ashx. If you want to use something else you will need to config IIS to do this, as per your managed handler img above.
I tend to use .ashx e.g: http://localhost/foo/my/httphandler/does/this.ashx
All you need to do (assuming you've compiled athe HttpHandler into a DLL and deployed it to the site) is add the necessary config.
<configuration>
<system.web>
<httpHandlers>
<add verb="*"
path="*.ashx"
type="MyApp.PublishingSystem.HttpHandlers.GroovyHandler, MyApp.PublishingSystem" />
</httpHandlers>
</system.web>
</configuration>
Obviously (?) you can change / restrict the scope using the path, e.g:
path="*.ashx"
path="*ListWidgets.ashx"
path="*Admin/ListWidgets.ashx"
More info here: http://msdn.microsoft.com/en-us/library/ms820032.aspx
An important gotcha to look out for is the order in which you declare your HttpHandlers in the config; from what I remember ones declared first take precedent. So in this example...
<add verb="*" path="*foo.ashx" type="MyApp.PublishingSystem.HttpHandlers.FooHandler, MyApp.PublishingSystem" />
<add verb="*" path="*.ashx" type="MyApp.PublishingSystem.HttpHandlers.GroovyHandler, MyApp.PublishingSystem" />
...the groovy handler will handle all HttpRequests except any that end in foo.ashx
By the way, I make use of HttpHanldrs in my open source .net CMS / app framework, you might find some helpful code there (?): http://morphfolia.codeplex.com/
Make sure the app pool's .NET Framework Version is set correctly...
I deployed a .NET 4.0 web app on a .NET 2.0 app pool and got this error. Set the app pool to v4.X and the ashx was served like a champ.

Categories