ASP.NET MVC website where users can add/remove pages - asp.net-mvc

I'm developing a website for a client, in which they want to be able to manage content and add/remove pages.
At the same time, some pages on the site will be interactive and provide custom reports for logged-in customers.
I've started developing the site in ASP.NET MVC, because I wanted full control over rendering.
However, I'm finding it difficult to conceptually model the site.
If users can add/remove pages, then how can there be a direct mapping of URLs to controllers?
I could do a single 'Page' controller and pass it a content ID, but that would mean that all the code in the site would sit under 1 class file.
I could make the custom/interactive pages sit under different controllers, but then, how will the customer be able to manage them?
I'm really lost with the usability angle of this as well. If I'm building custom interactive pages, how can the client add/remove them anyway? Won't that be modifying the structure of the application itself?

I'm having some problems understanding exactly what you're trying to get at with and what your problem is:
I could do a single 'Page' controller
and pass it a content ID, but that
would mean that all the code in the
site would sit under 1 class file.
I could make the custom/interactive
pages sit under different controllers,
but then, how will the customer be
able to manage them?
What's wrong with "a single class file"? Is your problem from a semantic perspective (ie, you don't want all URLs to begin with /pages)? Or just code management?
Assuming you're serving from a database, I would do the following:
Have a CMSController that accepts requests. It either a) checks the ID (maybe disregarding a stub), or b) takes the stub and looks it up in the db.
Return the content.
That way requests to /CMS/Page/4384 would be served up as you wish. You would then extend this in several ways. Put in a default action, so /CMS/4384 serves up the page. Then add a stub (/CMS/4384/Page-Title-Or-Whatever-Text). Set up additional routes such as /aboutus/ and /product_info/ to all point at your CMSController. Or just have a catchall point to the CMSController.
Also, the controller could open up an html file on the filesystem and serve that.
Does that help at all?
James

Related

How to add an mvc page to umbraco

I have Umbraco 7.5 and I need to know how to create normal MVC pages for adding new data to my site.
Lets say I have a Doctype "Node" in back-office. I want to let some people be able to add/edit some nodes without going through back-office. How can I do it?
I've tried to create add my view and controller (the MVC way), but apparently Umbraco hijacks all routing and my controller won't hit at all.
I've googled the matter (which is hard since I am not looking for Umbraco forms :| )and I've found this. But I prefer not to add my form as a part of other page. I mean, does it make sense to create a page in back office from type "something" and then on its template I do my add/edit form of another type? Seems strange, right?
I appreciate any ideas/ solution to this matter
You have a couple of options here. You can create a physical page for the editor to sit on, and add the editor as a SurfaceController action (basically an MVC Partial with Postback, that is still part of the Umbraco pipeline). Your form can then use the Content Service API to update the details. The advantage of this method is your code will have access to all of the Umbraco methods and templating out of the box. You could also use WebAPI controllers for the form if you want to do it all client side with JS requests.
You could also use route hijacking: https://our.umbraco.org/documentation/reference/routing/custom-controllers this allows you to have your own custom controllers for Umbraco routes, rather than using the default Umbraco ones. This is a bit more work to set up.
Finally, you can also tell Umbraco to ignore certain paths entirely, and you could run your controllers on those paths. The disadvantage here is that as the routes are being ignored by Umbraco, you don't automatically have access to all the useful Umbraco templating etc.
I've used the first method recently, and it works fine. The only caveat is that allowing users to edit nodes will fill up the version table quite quickly if a lot of users are editing a lot of nodes (every time a node is saved, a version is created). If you're going down this route, you may want to investigate something like Unversion: https://our.umbraco.org/projects/website-utilities/unversion/ which helps to keep old versions more manageable in situations like this.

Applying themes and styles in MVC 3.0

I come from ASP.NET Form development and now developing a MVC 3.0 application where when customer logs in she can select her different account from drop down:
The drop down contains:
Honda Car Insurance Account
Home Insurance Account
Ford Car Insurance Account.
When she selects one of the account the landing page changes with her historical details data etc. The application contains 4 more pages which has different contents for each account types.
In ASP.NET Form we could use themes and skins etc to apply the styles on the page based on which account the user has selected. However I don't see this seem to work on MVC.
Could anyone please suggest what would be the best way to achieve above in MVC?
Create one controller for each page and separarate views fro each accounts?
Should each page contentes be served by partial views?
Any other suggests?
NB: The JSON structure sent from controller is unique to each account type as each account have different properties.
Thank you very much for your help.
I would use a separate controller for each section. Then in the View folder for that controller, add a _ViewStart.cshtml file and inside it put
#{
Layout = "~/Views/Honda/_Layout.cshtml";
}
This will point to the layout page for this controller (Honda controller, but use whatever names you want.)
Then in the _Layout files you can add different layouts, css, etc.
That's probably the simplest way to get drastically different looking sections to the same site. Plus you would still have your default Home and Account controllers to keep a standard landing page, etc.
You can still use partial views, and anything else you would like with this setup. It may even mean faster loading time for the end user since their browser won't have to download css and other files that it's not using.
Edit
Here is a bit more information, ASP.NET MVC 3: Layouts with Razor from ScottGu's Blog
Because this code executes at the start of each View, we no longer
need to explicitly set the Layout in any of our individual view files
(except if we wanted to override the default value above).
Important: Because the _ViewStart.cshtml allows us to write code, we
can optionally make our Layout selection logic richer than just a
basic property set. For example: we could vary the Layout template
that we use depending on what type of device is accessing the site –
and have a phone or tablet optimized layout for those devices, and a
desktop optimized layout for PCs/Laptops. Or if we were building a
CMS system or common shared app that is used across multiple customers
we could select different layouts to use depending on the customer (or
their role) when accessing the site.
This enables a lot of UI flexibility. It also allows you to more
easily write view logic once, and avoid repeating it in multiple
places.

ASP.NET MVC Controller design

I have a question about how to design my controllers properly.
Project is fairly simple: blog, immage gallery with categories and images inside them, news secion.
However I don't know how to organize my controllers for this because I want to make somewhat admin panel where administrators can edit, add and modify these things. I've came up with 3 scenariosu so far...
Admin panel will have links to site/controller/edit, but layout for these action results will be different from standard one.
Admin controller will have all these actions like BlogAdd, BlogEdit so that url will be something like /site/admin/blogedit.
Create copies of Blog controller in admin folder so url will be like /site/admin/blog/edit - i sense problems with routing since 2 controllers with same name does not sound like a good idea, however I like ho URL looks in this situation.
What I'm trying to make is CMS somewhat similar to wordpress, where blog creation,editing and deletion is completely separated from default blog itself.
I suggest you stop thinking about URLs and Controllers being a 1->1 relationship. This will make things MUCH easier and less confusing. You can make the URLs work however you want with MVC's routing mechanism and there's no reason to restrict your controller design/organization because of the URLs you want, because you can always adapt the routing to with with the URLs you have in mind.
While building the website, just focus on the controllers (and the general interface) and ignore the URLs until you get to that point, and then when you come up with a good URL scheme go into the routing system and add the routes to connect to your existing controller actions as you want.
Once you code out your blogging engine you will have a much better idea of the user workflow and will probably find different ways to organize your URLs, and you can then reorganize your URLs without touching the controllers themselves.
As to your first requirement:
There are two ways to do this depending on your end goal. If your goal is to display the same core content, but have different user options available (different overall layout, additional buttons on the page, etc..) then the best idea is really to just pass in an IsAdministrator property in your view model, and make the slight changes to the page based on if that's true or false. The reason is because you still (most likely) want the core of the page to be the same, and this keeps you from duplicating code that is related to the core data (data that's being displayed for both admins and non-admins).
Edit: So in summary, organize your controllers based on what makes it easier to develop with, not based on how the user interacts with the system with. You can always change the latter, changing the former is harder and will make maintenance annoying.
You can create Areas in your MVC project and have your admin functionality in a controller in your admin area.
This will allow you to easily seperate your administration functionality from your general blog functionality.
That's how I'd do it.
Why don't you keep the routes the same and handle the different roles via security? For example:
/blog/name-of-topic/view to view a topic (all users)
/blog/name-of-topic/edit to edit a topic (only enabled for logged in users)
/blog/add to create new topics (only enabled for logged in users)
You can handle these actions in a single controller and decorate the actions that require logged users via the [Authorize] attribute. Same thing with the links on your views, you would enable the links to edit and add topics only to visible users.
You could still have a separate panel to allow admins to hit the aforementioned add/edit links .

ASP.NET MVC using IIS6: Block access to single view (register)

We are using MVC on IIS6. Our site is currently being opened up, but we need to restrict access to the register part of the site, but allow those who can register (i.e. from within our offices) still to sign in and use the site fully.
So inside office can access register and all other site.
Outside office cannot access register and but can access all other site.
Initially, we put file restrictions for the IPs of our offices on the register.aspx file in the views\accounts folder. We were pretty sure this was working, but today, we discover it isn't! Which thinking about it actually makes sense!
So is this possible?
We need to have the other aspx pages in the views\accounts folder usable as views whilst only blocking the register view.
Hope this makes sense!
Neil
Urls defined with ASP.NET MVC are configurable and not based on the folder or file where view page resides.
This means that you cannot use IIS to configure the access for this view pages.
You can filter access to the controllers (and so indirectly the view pages that are called by the view pages). This is done with Action Filtering. On how to create a custom action filter see this page.
So yes, it is possible to limit access to certain pages depending on the ip-address.
I have come across this kind of situation before, but the problem was solved by the way we write applications.
Whenever we've had an application with "some information displayed" and "a way to administer the data" we've always created separate UI projects over the top of the business logic. This isn't just to help with maintainability, it also means that the public bit can be deployed on a public website, while the admin bit can be accessed over the network - so there is no external access at all.
In your example, extracting out the two logical elements would mean that you can deploy two separate web projects with different access rules in IIS.
Another option would be to check the IP address in the executed code for the restricted page - IP addresses can be spoofed, so it's not a completely secure solution.

ASP.NET MVC controller actions design

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]

Resources