Is there a specific design practice for MVC type sites that need to have a lot of non-model related pages? I mean, it seems very silly to make a controller action for every single page; Yet at the same time, that seems to be the only way to realistically do it and adhere to standards. Is there any documentation or examples available for things like this?
When I speak of non-model pages, I mean things that are just display; Static information that you might use a standard HTML website layout for. But it has to be intermingled with other parts of the site that do require models and validation/etc.
Create a folder for your static content, and put in an ignore route for those pages. This causes those pages to be passed through directly to IIS for immediate display.
routes.IgnoreRoute("StaticPages/{*path}");
You can also load static HTML content into an existing View. This preserves your ability to work with dynamic content in the same page.
I don't think it sounds silly at all to make an action for every page. That's just how MVC works.
You can ignore some routes, as Robert Harvey suggests, but then you'll have the *.html extension on your static pages but not your internal ones, and you'll be unable to use the Url. and Html. helper methods for linking to MVC actions.
I think you should just go with the flow.
Another alternative was suggested for common static files such as help pages which is based more on a naming convention, but would allow for some flexibility in layout control in the view:
ASP.Net MVC Routing Strategy for Static Content
Related
I have a hard coded html website of 5 pages and want to convert it to mvc4.
what do i need to do?
Is there a tutorial or step by step guide outlining how to make .html files dynamic via MVC?
You are going to want to get a basic understanding of MVC and especially the routing before you change it over - you will avoid a lot of confusion and pitfalls in the future.
Basically, all you will need to do is create Controllers (dummy, for now) for your html, and copy the html into the respective View. This will all make sense when you understand the routing in the global.asax file. Then I would update the links to #Html.ActionLink syntax and move from there - likely next extracting a _Layout for universal design, etc.
Basically, read a quick tutorial at minimum, or you will just frustrate yourself.
If the pages have unique data on them then you could create a controller for each page, a model and a view.
If all of the the pages have similar information you could have one controller with various views.
I'm quiet newbie to ASP.NET MVC world. In Web Form we can write a user control and encapsulate all the details within. We can then reuse the control on N number of pages which is a good code-reuse.
I would like to do the same in MVC 3/4 and haven't had any lucks. Could someone please help me with how above can be achieved?
Thank you.
Probably the closest thing to an ASCX in MVC is a RenderAction.
Similarly to a user control, you can have your partial view binded to a specific action that is independent from the container view and it's action.
There is no exact equivilent. There are, however, ways to reuse code. You can create HtmlHelper extensions (like the Html.Whatever() methods), Or you can use Partial Views, or you can use templates. All of these do different things, but they offer various ways to reuse code.
What I'm trying to do is generate email content using different templates.
I think ASP.NET MVC could be a good fit for this. My controller would get the necessary data for the email and decide which view (template) to render. (It's more that just a simple mail-merge, there would need to be conditional blocks, foreach's, etc.)
I want to be able to store these templates in a database rather than as files in the web application, so new templates can be easily added from the web application itself.
Is this possible? I would prefer to be able to use the WebForms view engine, but would consider other view engines if that's not possible. I would ideally like to use typed views.
Unfortunately, the WebForms ViewEngine uses some internal classes to compile the aspx and ascx files, so this is not possible. That ViewEngine requires that the Views are available as files in a folder inside the site's root (virtual folder will also work IIRC).
There are other ViewEngines that may fit your purpose better, including some that use XSLT.
AFAIR it is possible to mix several ViewEngines in the same application, so you could use the WebForms engine for your normal web pages, and a different one for your emails.
You can indeed use multiple view engines in the same application. The framework will ask each of the engines whether it is capable of rendering the requested view. Check MvcContrib for other available view engines ...
As stated in the previous answer, the WebForms ViewEngine makes the assumption that the views (aspx, ascx) are stored physically on the file system, just like ASP.NET does (although in ASP.NET you have something like the VirtualPathProvider) that was - I believe - originally added to the framework to support e.g. SharePoint).
If you want to create your own view engine, you should implement IViewEngine, and add the view engine to the ViewEngines collection e.g. in Application_Start.
Phil Haack has a great article on something similar here.
I think it could be adapted to your needs.
Kindness,
Dan
You have to create your viewengine and so your buildmanager. Your viewengine can simply retreive the aspx part from a db and invoke the webform engine. Not easy but doable, it mostly depends on how bad you need this and how will it rewards you with a nice ROI.
I have an application that will support multiple sites. The site will be determined based on the url.
For example
http://myapp/site/abc123/...
and
http://myapp/site/xyz123/...
The site code will drive a lot of the functionality for example themes, available modules, etc...
Questions:
1-)I need to validate the site code is valid and if it isn't, it should direct the user to an info page. I was looking at using IRouteConstraint, is this appropriate? Are there other/better options?
2-)Any gotchas with this approach (using url to identify site)? Is there are better approach?
Solution
I ended up creating a Custom ActionFilter and check the sitecode in the OnActionExecuting event. That seems to work well and fit better than the IRouteConstraint.
The system I have implemented uses Urls to identify unique page content within a single site and the routing process is pretty straightforward. That being said, you may want to consider making use of Areas in your MVC application. With Areas you can have multiple sections to your website that all have their own MVC structure which can run semi-independently.
Essentially, you will have one base routing definition that lays out some defaults and then the rest of the "sites" will define their own routes pointing to controllers and views in a separate location. It's pretty easy to set up, you'll just need to make sure you're using version 2.0 of ASP.NET MVC. Here's a decent looking tutorial on ASP.NET MVC Areas and Routes. In the current model which MVC 2.0 supports you'll have a single Web project for each area, but that is not necessarily a requirement. Phil Haacked has some code for ASP.NET MVC Single Project Areas if you're looking for another example of the technique, although you, personally, will probably benefit more from the first article.
So long as you define good routes that have clear and measurable constraints, you shouldn't have too much trouble laying out the website you've described.
I ended up creating a Custom ActionFilter and check the sitecode in the OnActionExecuting event. That seems to work well and fit better than the IRouteConstraint.
I really like the way ASP.NET MVC works. I'd love to implement it on all new web projects moving forward, but I hit a snag in a prototype the other day that I really haven't found a good solution for, so I ask you, how would you design an MVC app that doesn't fit the typical REST pattern? As an example, the prototype I was designing would have several pages, but the pages themselves aren't necessarily bound to a domain model. For example, take a simple registration site, which might have the following pages:
/Default.aspx
/Register.aspx
/ThankYou.aspx
Occasionally, such a program might require an admin section to deal with such details as moderating sign ups or reviewing data. In a standard ASP.NET web app, I might add the following
/Admin/Default.aspx
/Admin/ListRegistrations.aspx
/Admin/ViewReports.aspx ...
Would it be an unacceptable deviation from the MVC pattern, in this case, to have two controllers such as:
Home->Index
Home->Register
Home->ThankYou
Admin->Index
Admin->ListRegistrations
Admin->Reports
My frustration with this is compounded by the fact that there is no real solid implementation of subcontrollers and areas yet. I'm aware of the "Areas" prototype put together by Phil Haack, but it's not very mature, and quite frankly, I'm not sure I like the way it's setup, but I don't really know how I'd like to see that work either.
I guess when I think MVC, I tend to think REST as well, and having controller actions that represent pages rather than actual entities or actions doesn't sit right with me. What do you think?
You can always mix ASP.NET Web Forms with MVC.
Just add
routes.IgnoreRoute("Pages/{*path}");
to your routing table and add traditional Web form pages to Pages folder of the application.
One mistake that newcomers to MVC make is to group actions into a controller for display reasons. In your case, instead of grouping the Register and ThankYou actions in with the homepage try separating them out into an AccountController as the MVC team has done in the sample project. You can use routing to set the Url's up however you want for the end-user.
As for your other actions, how about a ReportController? You could then additionally have an AdministrationController whose Index action/view contains links to various admin actions, including those on the ReportController.
Short Version: Group actions into a controller by function, not site navigation.
I usually ditch the "Home" controller as the first thing in a project and replace it with a "Page" controller. I use that one for anything that is "just" a page. Things like "FAQ", "Contact Us", etc. I do this at least partially because the default approach to the Home controller requires a new method being added every time you need even a basic, static page.
In that controller, I only have the one action: Display. That action gives all of those pages the same context object. I actually store the content for those pages in the database with a lookup "slug" and tie it into NVelocity templating, but even just static HTML or NVelocity templates in files would work too.
Anything else, like the others said, gets split into controllers by the "thing" being managed. So, a ReportController, User or AccountController, CartController, etc. Then the actions make much more sense.
When you're talking about listing the registered users, it's actually a list of users, so I'd have a UserController and do /User/Display/Registered/MostRecent or something similar. For the registration itself, /User/Register which would post to /User/SaveRegistration which could, in turn, redirect to /User/DisplayProfile/NewUserID or /Page/Display/Home from there.
You can have as many controllers as makes sense; that layout looks reasonable. Note that routes don't have to map directly to {controller}/{action}, but it keeps things simple. Looks fine to me - except I'd probably have ThankYou as a view - i.e. the Register [GET] perhaps uses a different view to Register [POST]