Convert ASP.Net MVC4 site to Azure - .net-4.0

I've created a ASP.Net MVC 4 web site that has several custom routes which are registered in the ~/App_Start/RouteConfig file.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Empty",
url: "",
defaults: new { controller = "Home", action = "Index", id = 0 }
);
routes.MapRoute(
name: "Session",
url: "{id}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
This site is working great outside of Azure and even works in the Azure emulator, but when I move it up to Azure, it's acting like there are no routes. For instance, when I try to navigate to the root of the web site I get an error stating:
403 - Forbidden: Access is denied.
You do not have permission to view this directory or page using the credentials that you supplied.
This made me think that the route simply wasn't working so I tried going to a another page like http://myapp.cloudapp.net/1234 (which should send 1234 into the home controller's index action. But that action gives me a 404 error.
I've checked my configuration against and new ASP.Net MVC 4 Azure project and they appear to be the same. I've also read through this which gave some pointers but ultimately didn't help.
Any advice on how to troubleshoot this?
Update
This is a WebRole project and is using .Net 4.0 (I already down converted from 4.5).

Have you tried setting a default page as per this article http://www.sunilhaste.com/2011/04/403-forbidden-access-is-denied-error.html
After you have uploaded your Web Role to Azure, you try to access the application and suddenly you get "403-Forbidden, Access denied"
error.
You are able access a page by providing it's complete url ex :- http://xyz.cloudapp.net/Pages/Home.aspx.
You don't have a default.aspx page present at the root level of your website. Solution :- The first thing that you should do is, to
check whether you have added below tag to the web.config file inside
system.webserver tag or not.
<add value="Pages/Home.aspx"/>
I also had had a similar issue and mine was fixed by setting the role to be 2008 R2. Someone in comments to the linked article says
change OS CONFIGURATION from MS SERVER 2008 SP2 to MS SERVER 2008 R2
Also see the following Asp.net and Azure - Can't no longer show my web application suggests checking you have <modules runAllManagedModulesForAllRequests="true" />
Also I assume you are making sure that MVC4 files are being deployed to Azure. Have your RDP'd to the machine and checked event log etc?

Related

Hosting MVC 4 Application in IIS Application

I have several applications deployed to IIS. I created a site for each application and mapped them using different port number. Recently, I was asked to use virtual directory instead of mapping them using different port number. I created the virtual directory and add a route for it. When I tried to test the application locally, I was getting a 403.14. After reading several post online, I made the following changes to my web.config file
<modules>
<remove name="UrlRoutingModule-4.0"/>
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule,
System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
preCondition="" />
</modules>
I am not getting a directory with all the files name. I updated my route in the
RouteConfig.cs file to
routes.MapRoute(
name: "Default",
url: "CollegeOfBusiness/{controller}/{action}/{id}",
defaults:
new { controller = "Account", action = "Logon", id = UrlParameter.Optional},
namespaces: new[] { "MyCollege.Controllers" }
);
After making those changes, I am not getting the 400.13 anymore; however, I am not getting the login page. I am getting a directory of all the files. I ran the command "aspnet_regiis /i" and then aspnet_regiis -ir to make sure that it was not a registration issue. I have not had any luck so far. I am looking for any information or resources that could help fix this issue.
Local System:
Windows 7
IIS 7.5
Visual Studio 2017
Asp.net MVC 4
Jquery 2.3
Update 07/03/2018 #9:45
I modified the route as shown below. I am not getting the directory listing anymore. However, POSTs and GETs are not routing to the appropriate controller.
The url when the page first loaded looked as shown here:
http://localhost/CollegeOfBusiness
I added the custom route below. It is added right above the default route.
RouteConfig.cs file to
routes.MapRoute(
name: "CollegeOfBusiness",
url: "CollegeOfBusiness/{controller}/{action}/{id}",
defaults:
new { controller = "Account", action = "Logon", id = UrlParameter.Optional},
namespaces: new[] { "MyCollege.Controllers" }
);
Then, I add the default route at the bottom.
RouteConfig.cs file to
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults:
new { controller = "Account", action = "Logon", id = UrlParameter.Optional},
namespaces: new[] { "MyCollege.Controllers" }
);
When the user clicked on login button, the post URL looked as follow:
/CollegeOfBusiness/Account/Logon
Finally, I was able to get it to work.
1. I removed the below custom route because it was not needed.
RouteConfig.cs file to
routes.MapRoute(
name: "CollegeOfBusiness",
url: "{controller}/{action}/{id}",
defaults:
new { controller = "Account", action = "Logon", id = UrlParameter.Optional},
namespaces: new[] { "MyCollege.Controllers" }
);
As suggested in this POST, I added the url to a div and get it based on the Id. I also change the src for all js and css file to use #Url.Action().
I had to prepend '/CollegeOfBusiness' in front of all requests
I changed the application pool to use a service account. This account did not have access to update the database, so I fixed that as well.

Unable to change swagger ui path

I'm using Swagger / Swashbuckle version 5.6 to generate documentation for my ASP.Net Web API 2 project.
By default API documentation is accessible at URL http://localhost:56081/swagger/ui/index
But, I want it should be available at http://localhost:56081/apihelp/
I searched a lot, tried changing settings in the SwaggerConfig.cs file but nothing seems to make this work.
So, is this even possible? if yes, can anyone help me with this ?
You can add the path to the call of EnableSwaggereUi,
e.g.:
SwaggerConfig.Register(HttpConfiguration config)
{
config.EnableSwaggerUi("apihelp/{*assetPath}", c =>
... // following lines omitted
}
You can then call the UI with the URL http://localhost:56081/apihelp/index
See https://github.com/domaindrivendev/Swashbuckle#custom-routes for reference.
Please note: the default setting 'swagger' redirects automatically to 'swagger/ui/index', but this custom setting does not automaically redirect to 'apihelp/index' when you just use 'apihelp'.
To achieve an automatic redirect you can add the route in WebApiConfig:
config.Routes.MapHttpRoute(
name: "Swagger UI",
routeTemplate: "apihelp",
defaults: null,
constraints: null,
handler: new RedirectHandler(message => message.RequestUri.ToString().TrimEnd('/'), "/index"));
The redirect code is based on v.karbovnichy's answer in How to redirect from root url to /swagger/ui/index?

Web Api in MVC4 project cannot Access Api Controller

I have an MVC4 project with many controllers. I added an Api controller called BatchDetailsController in the root directory of the project.
I also created a WebApiConfig class as below
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
I also invoke the above register method from global.asax as
WebApiConfig.Register(GlobalConfiguration.Configuration);
in Application_Start
Now I have tried to access the controller by using then Urls
/BatchDetails
/api/BatchDetails
/BatchDetails/Get
/api/BatchDetails/Get
All of them return 404
What is the URL I need to use in this case
for example when using visual studio to debug/host the project the url would be http://localhost:port/api/BatchDetals/{method}
Right click on the project and see if IIS express is selected and note the port number. The project should come up via run/f5 in visual studio at the Project URL.
If not I would re-install IIS8 express.

MVC routing under a domain

I have just published an MVC application. It has a Home controller with a method Create.
The URL is http://www.myurl.com
The name of the virtual directory in IIS is myurl.
When I submit the form that posts to Home/Create I'm getting an error because it's trying to send the data to:
http://www.myurl.com/myurl/Home/Create
rather than:
http://www.myurl.com/Home/Create
I tried adding this route:
routes.MapRoute(
"test",
"Home/CreateNewPlayer",
new { controller = "Home", action = "CreateNewPlayer" }
);
but that hasn't made any difference. Can someone please help me out?
You should not host your application in a virtual directory but rather directly inside the website which has a binding to the www.myurl.com domain.

Creating a Catch-All Route

I've found several examples online (especially on StackOverflow) for creating a catch-all route in ASP.NET MVC, but this doesn't appear to be working for me in MVC4:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("elfinder.connector");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "CatchAll",
url: "{*url}",
defaults: new { controller = "Home", action = "CatchAll" }
);
}
With the controller action defined as:
public ActionResult CatchAll(string url)
{
// catch the URL and use it for something
}
The goal here is to intercept all potential 404 errors and, depending on the URL, either respond with a 404 or with something else. However, I never end up in the CatchAll action, I just get a default 404 for URLs like:
~/foo
~/this/is/a/test/url
Am I doing something wrong here? I'd like to avoid having to catch the errors in Application_Error and, if it's a 404, re-forward from there. It just seems kind of messy. It seems to me that the proper way to handle these requests would be to simply route them to the correct action, no?
UPDATE: While the URL purist in me wants to avoid the use of Response.Redirect, I'm currently trying the following as a global catch-all for requests:
protected void Application_Error()
{
Exception exception = Server.GetLastError();
HttpException httpException = exception as HttpException;
if (httpException != null)
if (httpException.GetHttpCode() == 404)
{
Server.ClearError();
Response.Redirect(String.Format("~/Home/CatchAll/?url={0}", Request.Path));
}
}
However, this only works if the structure of the URL matches a route. Otherwise it looks like IIS doesn't even send the request to the application, it just returns a 404 directly. I need pretty much a global handler where any URL requested of the website which doesn't map to an action gets directed.
UPDATE: It looks like a combination of two things should do the trick for me. First, catching 404s in Application_Error (or Application_EndRequest as some people suggest, either way works for my needs) covers anything that matches a route structure but doesn't find an action. However, there's still the case of requests which don't match a route structure.
For varying reasons, I don't want to have to tweak IIS for this. The solution should be contained within the application itself. Luckily, I can guarantee the latest .NET and IIS, which allows me to use Web.config settings to instruct IIS on how to handle errors. So I'm currently trying this:
<httpErrors errorMode="Custom" defaultResponseMode="Redirect" defaultPath="/Home/CatchAll">
<clear/>
</httpErrors>
However, this doesn't appear to be quite right. It is affecting IIS in that the error response has changed, but it's still an error response. Which is:
HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
So it looks like I'm on the right track, I'm just having a difficult time finding a working example of using httpErrors in the Web.config to send all 404s (or even all errors, it makes little difference for my needs) to an action.