Adding asp.net.mvc to ASP.NET: Controllers folder - asp.net

I have an ASP.NET application, and I am trying to turn this into a hybrid ASP.NET / ASP.NET.MVC 4.0 application.
I tried to create a folder named "Controllers", and place a .cs file in there:
public class PlayerGroupController : Controller
{
public PlayerGroupController()
{
}
public string Index()
{
return "Hello World!";
}
public ActionResult LayoutTemplates()
{
return View();
}
}
Any attempt to access "PlayerGroup/LayoutTemplates" doesn't work (just get a "Not Found" error)
I then moved this file into App_Code, and it works fine. I'm glad I got something working, but I would rather follow the convention of controller classes being in the folder named Controllers.
Is there some magic setting I can set somewhere so that it starts recognizing Controllers as a code folder?

If the project is configured as a Web Site Project then all code files (*.cs) must be in ~/App_Code or in subfolders thereof. If the project is a Web Application Project, code files can go anywhere in the project and be compiled by VS into a DLL that ends up in the ~/bin directory, which then gets loaded by ASP.NET.
MVC is geared specifically towards the Web Application Project (WAP), so I recommend creating a new WAP and copying all the files into that, and then going from there.

Related

Host Asp.Net MVC in IIS hides Views-Folders and .cshtml

When I host my Asp.Net MVC inside my default IIS, it does neither show .cshtml files, nor the Views folder at all. Even when directory browsing, these folders are missing. If I create some file in the Views folder I cannot access it either. If I create some file in another folder I can access it.
This is my routing configuration
I think this should be a rather basic setup question. Do I have to manually add MVC support?
My IIS is running in my docker container on the basis of windowsservercore. Setup as follows:
FROM microsoft/windowsservercore
SHELL ["powershell"]
RUN Install-WindowsFeature NET-Framework-45-ASPNET ; \
Install-WindowsFeature Web-Asp-Net45
Routing doesn't go to views it goes to controllers. It is the controllers that process and then render the views. Additionally, there is no physical correlation between the URL that you provide and the view location - that is entirely based on how the routes are setup.
It is normal and expected behavior for IIS to block direct access to the Views folder, since these are never used by the browser directly.
The Views are convention-based by default. The convention they use is Views\<ControllerName>\<ActionName>.cshtml. When a view is in the correct corresponding location, the action method can simply return View(); and the view will be rendered.
The view Views\tst.cshtml will only be rendered if you have passed the virtual location of the view to the View method (for example, return View("~/Views/tst.cshtml");. This is because it does not match any of the "normal" MVC conventions.
Since you have not provided any examples of what your controller or action names are (or even if you have any), I will provide a basic example from the MVC template project.
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
With the above controller and the Default route, if you pass the URL /Home/About (Home matching HomeController, and About matching the About method), the About method will run, and the view at \Views\Home\About.cshtml will be rendered.
Reference: Understanding Models, Views, and Controllers (C#)

Routing for Single Page Application in ASP.NET Core

I have a Single Page Application written in JavaScript, and I use HTML5 history API to handle URLs on the client side. This means any URLs sent to the server should cause the server to render the same page.
In the ASP.NET MVC 5 I wrote this code to do this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
// ...
routes.Add(new Route("{*path}", new MyRouteHandler()));
}
}
public class MyRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return WebPageHttpHandler.CreateFromVirtualPath("~/index.cshtml");
}
}
This worked really well. No matter what URL the server gets, it renders index.cshtml. Note that I am able to use a .cshtml file (as opposed to an .html file) which means I can have some C# code to dynamically change what .js scripts are included, append version numbers to .css files, and so on. What's more, I didn't have to implement controllers and views and so on just to render this .cshtml file.
Now we come to the question: How do you do this in ASP.NET Core? I have been reading the documentation, but I don't see how to render a .cshtml file without adding controller classes, view folders and other rigmarole.
Anyone know the equivalent code in ASP.NET Core?
Currently to run a CSHTML page "the normal way" in ASP.NET Core requires using ASP.NET Core MVC.
However, there is a planned feature that is being worked on that is somewhat similar to ASP.NET (non-Core) Web Pages, where you can have standalone CSHTML files. That feature is being tracked here: https://github.com/aspnet/Mvc/issues/494 (and as far as naming for the new feature, that is being tracked here: https://github.com/aspnet/Mvc/issues/5208).
There's also a sample of how to render an MVC view to a string (e.g. to generate an email, report, etc.), and that sample is available here: https://github.com/aspnet/Entropy/tree/dev/samples/Mvc.RenderViewToString
But to use this sample in the scenario you describe, you'd have to do some extra plumbing to wire it up as its own middleware (not a lot of plumbing; just a little!).
It's also worth noting that in your scenario you probably don't want all URLs going to this one view, because you still need the static files middleware running first to handle the CSS, JS, images, and other static content. Presumably you just want all other URLs to go to this dynamic view.

ASP.NET Web.Api plugin architecture

Can you suggest me some articles or code samples about plugin architecture in web api?
Currently I'm thinking about this scenario: to have 1, centralized api gateway, where every client sends request, and have different applications controllers in Plugins folder. If someone wants to add new service, writes it's own controllers and puts dll files in Plugin folder.
For locating controller classes at run time, you can write an assembly resolver, like this.
public class MyAssembliesResolver : DefaultAssembliesResolver
{
public override ICollection<Assembly> GetAssemblies()
{
List<Assembly> assemblies = new List<Assembly>(base.GetAssemblies());
// Add all plugin assemblies containing the controller classes
assemblies.Add(Assembly.LoadFrom(#"C:\Plugins\MyAssembly.dll"));
return assemblies;
}
}
Then, add this line to the Register method in WebApiConfig.
config.Services.Replace(typeof(IAssembliesResolver), new MyAssembliesResolver());
With this, the request will still need to be sent to the individual controller even though the controller classes can come from assemblies in the plugin folder. For example, if MyAssembly.dll in the plugins folder contains CarsController, the URI to hit this controller will be /api/cars.

How do I redirect to the cshtml page created inside shared folder in ASP.NET MVC3

Please help me out how do I redirect to a .cshtml page which is created inside a shared folder.
I want something like this
href="#Url.Content("Shared/UnderConstruction")"
Here it's not getting redirecting to the UnderConstruction page, which I created.
You cannot redirect to anything that's stored inside the ~/Views folder including the ~/Views/Shared. This folder is simply not served by ASP.NET MVC and cannot be accessed directly. Also notice that in ASP.NET MVC you are not serving .cshtml pages directly. You are always passing through controller action that return views and those views might represent .cshtml pages.
Now if you have some Shared folder directly under the site root ~/Shared, then you can do this:
construction
In ASP.NET MVC3 you can't render views directly by calling the files directly. They can only be served via controllers.
In order to call the view in your shared folder you woul have to do something similar to the following:
public class HomeController : Controller
{
public ActionResult About()
{
return View("Construction");
}
}
If you want to display a page at url "shared/underconstruction" as per the other posts:
Create controller SharedController.
Define action "UnderConstruction"
Create "UnderConstruction.cshtml" in Views/Shared/ folder.
Map URL "Shared/{action}" , new { Controller = "Shared" } if you want to be explicit.
Give that a shot... to be honest even I don't know if this will work, and you will pollute your "Shared" folder. You could rename existing Shared folder to something else, maybe, and modify ViewStart.cshtml to point to new folder, maybe.
In ASP.NET MVC you can only redirect to controllers, and the controllers return a view. You can access views in Shared the same way as your normal controller views, by their name. ASP.NET MVC first looks in your controller view folder then in your shared view folder when resolving view names.

protecting files with asp.net (mvc)

I want to protect the files in a specific directory so that people cannot link to them - but I still need my program to be capable of rendering them, so password protecting the actual folder won't work. Is there any way to facilitate this in ASP.NET MVC? Obviously it's more about ASP.NET, not MVC - but I can't make use of things like Session State and Postback and such...
You could put that directory outside of the web app's root directory (so that it can't be accessed using some copied URL) or into a directory where you deny any read access using a web.config file.
Then access the files through an action which requires the current user to be authorized, e.g:
public class FileController : Controller
{
[Authorize]
public ActionResult Get(string file)
{
return new File(Path.Combine(_rootPath, file);
}
}
Then you can access the files through an action URL, e.g. http://server/app/File/Get/test.txt.

Resources