2

I would like to display the view in the folder if no controller/action matches.

For example www.site.com/Home/Index, if I have the normal default route {controller}/{action}/{id} then I need a HomeController with method Index. And there is a folder in Views folder called Home and the file Index.cshtml

If i try www.site.com/About/Index i need to create the AboutController and the method index. But I have just the folder About and file Index.cshtml.

I would like that if the default route does not match but I have a Folder and a File in the Views folder that match the patern: {controller} is the folder {action} is the view; then that view is displayed.

How could I achive that?

4 Answers 4

4

For missing actions you can override HandleUnknownAction.

For missing controllers you can implement a custom DefaultControllerFactory and override GetControllerInstance with something like this:

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {

   if (controllerType == null)
      return new DumbController();

   return base.GetControllerInstance(requestContext, controllerType);
}

class DumbController : Controller {

   protected override void HandleUnknownAction(string actionName) {

      try {
         View(actionName).ExecuteResult(this.ControllerContext);
      } catch (Exception ex) {
         throw new HttpException(404, "Not Found", ex);
      }
   }
}
Sign up to request clarification or add additional context in comments.

6 Comments

why not just put cshtml files somewhere else rather than try to work around a missing controller?
@AdamTuliper Ask the OP. When I first started with MVC I had trouble using the MVC master page with standalone pages, because the page had to inherit from ViewPage to be used with a ViewMasterPage. Maybe there's a legitimate reason for what he's asking. If I could keep all pages under Views I would do it.
Pages kept under views are not addressable because it violates the flow of an MVC application. It makes it an MV application. Since /Views is meant for integration with the MVC pattern and the runtime has a built in flow it generally looks for, anything not fitting that pattern should be kept elsewhere. I can think of at least two security issues this can cause. Imagine being a new developer and being handed this app and trying to understand why in some cases a view is directly addressable and in other cases its not =- all within the same /Views folder. It could make you mad.
@AdamTuliper Yes, there are potential security issues, no one should use this code without testing it first. But this doesn't go against MVC, there is a controller, which returns a view if there is one that matches.
In what was asked, this is just a 'v' and excludes the 'c' a part of the MVC pattern. Views folderis not readable to keep it inline with the MVC pattern. This code isn't very testable as any future missing controller can lead to an addressable view. If I can find a way to skip a route by say a failed regex match then I can directly address a view. This shouldn't be allowed at all under any circumstances. There's a reason the team didn't want this to occur. Stick to convention.
|
2

I came across the same issue recently while developing AJAX web applications where most of the pages don't actually need a controller (all the data is returned via Web API calls).

It seemed inefficient to have dozens of controllers all with a single action returning the view so I developed the ControllerLess plugin which includes a default view controller behind the scenes with a single action.

If you create a controller for your view, then MVC will use that. However, if you create a view without a controller, the request is re-routed via the default plugin controller.

It works with C# and VB.NET and us available at https://www.nuget.org/packages/ControllerLess

The source code is also available on GitHub at https://github.com/brentj73/ControllerLess

Comments

1

You cannot and shouldn't the way you want. Views cannot be addressed by design (in the web.config in the /views folder theres an HttpNotFoundHandler mapped to * to ensure this)

With that said, what you want here is not really standard so why do you want to do this, maybe we can come up with a better suggestion based on the reason behind this?

4 Comments

For example the designer creates a new page but that page will be static, I don't want to code the controller and action just for displaying the new page. Did not like your anwser. See @Max-Toro was much more helpfull.
Like it or not- Theres a reason for this design you are going against. Simply put your cshtml files in another location and you can address them there. what you are doing is hacky and would be considered as such in any decent MVC architects mind. So consider 'helpful' how you want as this was sound advice I gave you from someone who teaches MVC :)
I'm simply trying to help you on what I've seen is not a good practice. I've written many MVC apps, train others on this, blog on this, and talk on this at some of the largest national conferences and I have yet heard of anyone who is opposed to simply creating another folder for non-controller sourced views to stick with the mvc flow. Microsoft already made the statement on proper design here on their platform by disabling being able to directly address views in there. plenty of developers go against the proper way something was designed, whats one more? security issues here as well.
I assure you there are security issues here too, but I guess security isn't meaningful either.
0

Never tried this, but here's a thought. You can setup constraints for the routes, and thus you should be able to create a route matching "{folder}/{file}" where you constraint them to valid values (you can google this, or seach her on SO), and set it to run on a FileController (arbitrary name) with some default action. Then, in that action, simply return the desired view. Something like:

public class FileController : Controller {
    public ActionResult Default(string folder, string file) {
        return View(folder + "/" + file);
    }
}

1 Comment

Sorry but that does not work when you mix it with the normal routes. But thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.