Using Driver.cs for front end?

Topics: General, Troubleshooting, Writing modules
Nov 14, 2012 at 10:15 PM
Edited Nov 14, 2012 at 10:17 PM

Very new to Orchard. I was following this blog series and was trying to have the user input on the front end. I simply added [Themed] to my controller actions and created my shapes in Parts and EditorTemplates/Parts respectively after creating the Driver.cs.

I also created a Route.cs file. This worked fine without the inputs/shapes/drivers (i.e., the page displayed). However, now when I run everything I am getting the "View" not found error message, which I understand is looking for what I set up in Route.cs.

I am confused by the docs/examples/modules out there. I am partly of the mind that Driver.cs is strictly for Admin views, although I see some chatter about using them in the front-end.

Is it that I should change my Route.cs file (and if so how)? Or how is it that I can hook the Driver.cs Editor portion to the route I set up? Or am I just completely mistaken?

What I am after is trying to get some user input on the front-end and then store it for use by the admin in the back-end. Nothing fancy. I looked at the Cyberstride Contact form module but I had trouble parsing out the parts I didn't need (like creating a Contact Form content part) and getting it to work. Specifically, I was confused by how the author used a ContactDriver and a ContactFormDriver.

Any guidance? Thanks.

Nov 15, 2012 at 11:26 AM

Difficult to diagnose specific problems without any code or error messages (seriously, posting that really *really* helps!).

I also created a Route.cs file. This worked fine without the inputs/shapes/drivers (i.e., the page displayed). However, now when I run everything I am getting the "View" not found error message, which I understand is looking for what I set up in Route.cs.

No, either you have a controller or a content part that is looking for a view that is not there. The error message should contain a long list of all the locations searched - check your spelling in your driver/filenames of views etc.

I am confused by the docs/examples/modules out there. I am partly of the mind that Driver.cs is strictly for Admin views, although I see some chatter about using them in the front-end.

Drivers are not strictly for use in the dashboard. They tend to have three key methods: Display, and Editor (of which there is an override - so 2 x Editors). Display is called when displaying the content part on the front end (invoked from a called to IContentManager.BuildDisplay.

Editor (the override with 2 arguments), is called when on the dashboard, and you are displaying the editor to the user. The 3 argument override of Editor is used to collect values posted by the editor, and then to update the relevant content part.

So as an example, consider the BodyPart. Then Editor() is called it returns a shape which renders a nice editor which lets you enter some text etc, and this is part of a larger form. Submitting this form will invoke the override of Editor() which gets the values posted by the user and updates the database for that BodyPart. When you go and view that content item from the front end, Display() is called, and it returns a shape which displays the HTML entered from the dashboard.

Is it that I should change my Route.cs file (and if so how)? Or how is it that I can hook the Driver.cs Editor portion to the route I set up? Or am I just completely mistaken?

Again, without any error messages/code it is difficult to say - from what you've said above it sounds like the issue occurs when trying to locate a view for a particular part. If it were a problem with routes then you would be getting 404s or errors about not being able to find an action method or something like that. 

What I am after is trying to get some user input on the front-end and then store it for use by the admin in the back-end. Nothing fancy. I looked at the Cyberstride Contact form module but I had trouble parsing out the parts I didn't need (like creating a Contact Form content part) and getting it to work. Specifically, I was confused by how the author used a ContactDriver and a ContactFormDriver.

With Orchard, there is always more than one way to do anything ;) How the cyberstride module seems to work is that they have a driver with a Display() method outputting a form, which posts to a controller to collect the posted information. The key parts are really Views\Parts\ContactForm.cshtml, Drivers\ContactFormDriver.cs (in particular Display()), and Controllers\ContactController.cs (see the Create() method). You can probably ignore ContactPart/ContactDriver as that seems to be for logging contacts - if you just want to collect and save data it is largely irrelevant for now.

Nov 16, 2012 at 3:19 AM
Edited Nov 16, 2012 at 4:32 PM

@kobowi, thank you for the detailed explanation. It's very helpful to my understanding of these concepts.

I should have posted code with my question. 

ComputerDriver.cs:

 

protected override DriverResult Display(ComputerRequisistionPart part, string displayType, dynamic shapeHelper)
        {
            return ContentShape("Parts_Computer_Requisition", () => shapeHelper.Parts_Computer_Requisition(
                    FirstName: part.FirstName,
                    EMail: part.EMail,
                    ComputerType: part.ComputerType,
                    ComputerRequisitionCreatedUtc: part.ComputerRequisitionCreatedUtc
            ));
        }

 

I have a file named Computer.Requisition.cshtml saved in the ~/Views/Parts/ folder.

ComputerController.cs:

 

[Themed]
public ActionResult Requisition()
        {
            var model= new ComputerRequisitionViewModel();
            return View(model);
        }

 

Route.cs:

 

new RouteDescriptor
        {
            Priority=5,
            Route = new Route(
                "Computer/Requisition", 
                new RouteValueDictionary {
                    {"area", "ICC"},
                    {"controller","Computer"},
                    {"action","Requisition"}
                },
                new RouteValueDictionary(),
                new RouteValueDictionary{
                    {"area", "ICC"}
                },
                new MvcRouteHandler())
        },

Don't know if that helps. Any insight? Thanks, again.

Nov 16, 2012 at 9:25 AM

Can you post the error message you were getting as well?

Nov 16, 2012 at 4:32 PM

It's a lengthy one, so lemme just post the relevant portion:

Server Error in '/OrchardLocal' Application.

The view 'Requisition' or its master was not found or no view engine supports the searched locations. The following locations were searched:

All the locations reference the Theme folders, the module folder (ICC), and all other module folders. Specifically, they almost all look for ~/Views/Computer/Requisition.cshtml or ~Views/Requisition.cshtml therein, rather than looking for ~/Views/Parts/Computer.Requisition.cshtml.

I edited a typo I made inserting the code in the thread above (I did slap [Themed] on the ActionResult, and the variable I didn't type out properly).

Thanks!

Coordinator
Nov 16, 2012 at 6:00 PM

Well, yes, your driver is irrelevant here, as you are going through a controller action. It is looking for a view named the same as your controller action (Requisition) and not finding it.

Nov 16, 2012 at 8:28 PM

Thanks @bertrandleroy. I see I was barking up the wrong tree. Looking at some other modules out there I see I can implement what I want using something like:

var shape = _orchardServices.New.Computer_Requisition();

in my controller. The drawback (which reading some posts seems to confirm) is that all of my views have to be in ~/Views/ folder (e.g., ~/Views/Computer.Requisition.cshtml). For one or two files this seems okay, but for a ton of files I'll have to figure out some way to organize them.

Again, thanks.