Apologies if this is a duplicate/repost/answered previously but I've searched through the forums, StackOverflow and other sources and am struggling with the concept of a custom controller in Umbraco.
This is my first Umbraco project and it's going great so far. All the content pages are driven by Umbraco, it's rendering perfectly on the front end and back office is a breeze to use, however I'm facing an issue with my first form post.
I've created the form and it's purpose is to take the filter criteria posted and return a list of matching results. The route is configured properly and when posting, my custom controller is called. I have the controller inheriting from RenderMvcController and at the moment a simple view model being returned. I'm getting a null reference on the view model as IPublishedContent is null. This leads me to think I'm not using the correct architecture for what I want to do, or I'm missing a step.
Here is all the relevant code:
public class EventSpaceSearchResultsViewModel : RenderModel
{
public EventSpaceSearchResultsViewModel() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent)
{ }
public string TestString
{
get { return "This is a test!"; }
}
}
public class SpacesController : RenderMvcController
{
[HttpPost]
public ActionResult Search(EventSpaceSearchViewModel searchModel)
{
var model = new EventSpaceSearchResultsViewModel();
return View(model);
}
}
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 6: public class EventSpaceSearchResultsViewModel : RenderModel
Line 7: {
Line 8: public EventSpaceSearchResultsViewModel() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent)
Line 9: {
Line 10: }
Am I doing this correctly or is there a better way to take a form post and display my own view model?
But, for what I see on your code, you're creating a search form and for that I wouldn't create a POST, but a GET so the search can be reused, bookmarked, etc. To do this I'd create a controller inheriting from RenderMVCController and I'll get the parameters from the query string, then I'd do the search and return the view with the results.
To get more info about RenderMVCControllers go to: https://our.umbraco.org/documentation/Reference/Mvc/custom-controllers
If you need more help it'd be great if you post your form code and explain a little bit what you want to do.
I've looked at using surface controllers, but they appear to need an Umbraco page as the return view if I'm not mistaken? At the moment, the form code is created in a partial view (and it's really just a few drop downs, nothing special) and it's included in a number of pages. I want the results to be displayed on a different page than the one the partial view is rendered on which is why I went the RenderMvcController option.
If I use a surface controller, is the correct implementation to create a "Search Results" document type and have the surface controller redirect to that?
Thanks for the advice on the form method, I've always simply used POST for forms but changing to a GET is a great idea.
Yes, the result of a surface controller must be an Umbraco page.
I made a demo using a RenderMvcController as you require, this is the code:
// The form (which is in a partial view)
<form action="/search-results" method="POST">
<input type="text" id="query" />
<input type="submit" value="Submit" />
</form>
// Request Model
public class SearchParameters
{
public string Query { get; set; }
}
// Results Model
public class SearchResults : RenderModel
{
public SearchResults() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent) { }
public string TestString { get { return "Foo"; } }
}
// Controller
public class SearchResultsController : RenderMvcController
{
[HttpPost]
public ActionResult Index(SearchParameters searchModel)
{
var model = new SearchResults();
return View("SearchResults", model);
}
}
// View
@inherits UmbracoViewPage<UmbracoPlayground.Models.SearchResults>
@{
Layout = null;
}
@Model.TestString
@Model.Content.GetPropertyValue("label") <!-- Just to make sure I can read properties from Umbraco -->
That's all! in Umbraco I've got a document type called SearchResults and a content page of that type to make the routing works.
Ah perfect, thank you so much for your help. Once I realised I needed to create the document type & content page it all slotted into place! Coming from an Orchard background where you could create your own controllers, models, views and make your own route it took that little bit of information to put it all into place.
Advice on custom controllers handling FORM posts
Hi All,
Apologies if this is a duplicate/repost/answered previously but I've searched through the forums, StackOverflow and other sources and am struggling with the concept of a custom controller in Umbraco.
This is my first Umbraco project and it's going great so far. All the content pages are driven by Umbraco, it's rendering perfectly on the front end and back office is a breeze to use, however I'm facing an issue with my first form post.
I've created the form and it's purpose is to take the filter criteria posted and return a list of matching results. The route is configured properly and when posting, my custom controller is called. I have the controller inheriting from RenderMvcController and at the moment a simple view model being returned. I'm getting a null reference on the view model as IPublishedContent is null. This leads me to think I'm not using the correct architecture for what I want to do, or I'm missing a step.
Here is all the relevant code:
And the error message is:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 6: public class EventSpaceSearchResultsViewModel : RenderModel Line 7: { Line 8: public EventSpaceSearchResultsViewModel() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent) Line 9: { Line 10: }
Am I doing this correctly or is there a better way to take a form post and display my own view model?
Thanks in advance!
Hi David,
Create a POST using a RenderMVCController seems a little bit weird to me. To submit data in Umbraco you should use surface controllers, more info here: https://our.umbraco.org/documentation/Reference/Templating/Mvc/surface-controllers
But, for what I see on your code, you're creating a search form and for that I wouldn't create a POST, but a GET so the search can be reused, bookmarked, etc. To do this I'd create a controller inheriting from RenderMVCController and I'll get the parameters from the query string, then I'd do the search and return the view with the results. To get more info about RenderMVCControllers go to: https://our.umbraco.org/documentation/Reference/Mvc/custom-controllers
If you need more help it'd be great if you post your form code and explain a little bit what you want to do.
Cheers!
Hi,
Thanks for your reply.
I've looked at using surface controllers, but they appear to need an Umbraco page as the return view if I'm not mistaken? At the moment, the form code is created in a partial view (and it's really just a few drop downs, nothing special) and it's included in a number of pages. I want the results to be displayed on a different page than the one the partial view is rendered on which is why I went the RenderMvcController option.
If I use a surface controller, is the correct implementation to create a "Search Results" document type and have the surface controller redirect to that?
Thanks for the advice on the form method, I've always simply used POST for forms but changing to a GET is a great idea.
Cheers
Hi David,
Yes, the result of a surface controller must be an Umbraco page.
I made a demo using a RenderMvcController as you require, this is the code:
That's all! in Umbraco I've got a document type called SearchResults and a content page of that type to make the routing works.
Hope this helps.
Cheers!
Ah perfect, thank you so much for your help. Once I realised I needed to create the document type & content page it all slotted into place! Coming from an Orchard background where you could create your own controllers, models, views and make your own route it took that little bit of information to put it all into place.
Dear Cristhian Amaya,
i see your solution using custom controller
but i stuck where to pur form part and where to place view
plz guide
Thanks sir
and Dear David Redmond
i m also working solution like your search page can you plz share working code thanks
is working on a reply...