With regard to SurfaceControllers, I found this commit where Shannon has refactored all things SurfaceControllers for .net core, and this comment here:
Yep these routes are really just for postbacks. For the most part
SurfaceControllers are only for: post backs and 'child actions' (but
those don't exist anymore). I created a separate task to test view
components with forms to ensure they work.
So it seems like ViewComponents could be pretty cool within the context of Umbraco, you can inject services into their constructor using di (think umbraco services) and pass in additonal parameters (like macros) and they aren't part of the request eg like child actions - but it seems using either invoke or invokeasync, you can conjure up a model in C# and send it through to a View...
... which if I've understood, will be pretty cool.
With the constructor injection, there isn't any need for any special UmbracoViewComponent base class or anything to access the cache...
So, where - in the past - we used to build e.g. a contact form like this :
1 SurfaceController with 2 actions
1 for the HttpGet
1 for the HttpPost
we now need :
1 ViewComponent to render the form
1 SurfaceController to receive the HttpPost
Correct? Then how do we implement a Post-Redirect-Get scenario (e.g. https://andrewlock.net/post-redirect-get-using-tempdata-in-asp-net-core/) where - upon receiving an invalid Modelstate - we use ActionFilters to put the ModelState in tempdata, redirect back to the current page and fetch the ModelState from tempdata again?
Been trying, but ViewComponents don't have any filters and I'm really puzzled by this new approach.
I'm currently working on our first v9 site and like you I find it quite strange that there is the need for a ViewComponent and Controller to do something "simple" like a contact form.
It does seem to work though it's a little awkward to set up: ViewComponent class that renders a view containing a form. The form submits to a SurfaceController class action.
When I add a ModelState error in the SurfaceController action and return CurrentUmbracoPage() it does render the form with the entered data and displays the ModelState errors.
But I did run into an issue. The form in the ViewComponent view has to be started with the Html.BeginUmbracoForm() helper. While you can use Tag Helpers to render the form fields, labels and validations you can't use the Form Tag Helper to render the form tag. A security header (or cookie)? is missing and the form won't submit.
I did run across this post where a guy builds a SurfaceController class that is also the ViewComponent ... thus marrying the two in one class.
Render action from Surface Controller
Seems like Html.Action and Html.RenderAction is replaced by something new called ViewComponents in .net 5.
Does this mean we can't render actions from SurfaceControllers in our views with
@Html.RenderAction("MyActionMethod", "MySurfaceController")
anymore?Hi Soren
I don't know but your question got me snooping, and I thought I'd write down some things I found:
so yes ChildActions are not a thing it seems in .net core:
https://www.davepaquette.com/archive/2016/01/02/goodbye-child-actions-hello-view-components.aspx
With regard to SurfaceControllers, I found this commit where Shannon has refactored all things SurfaceControllers for .net core, and this comment here:
https://github.com/umbraco/Umbraco-CMS/pull/9762#issuecomment-774797292
So this further PR: https://github.com/umbraco/Umbraco-CMS/pull/9915 is related to Forms and mentions testing with a ViewComponent...
And this is kinda an example ViewComponent in the core:
https://github.com/umbraco/Umbraco-CMS/blob/netcore/dev/src/Umbraco.Web.Common/Macros/PartialViewMacroViewComponent.cs
So it seems like ViewComponents could be pretty cool within the context of Umbraco, you can inject services into their constructor using di (think umbraco services) and pass in additonal parameters (like macros) and they aren't part of the request eg like child actions - but it seems using either invoke or invokeasync, you can conjure up a model in C# and send it through to a View...
... which if I've understood, will be pretty cool.
With the constructor injection, there isn't any need for any special UmbracoViewComponent base class or anything to access the cache...
... all interesting stuff.
Not sure that answers the question though!
regards
marc
Thanks Marc, I did browse around looking for ViewComponents, but obviously you were better than me :)
That PartialViewMacro thing seems to be controllerbased in v8, so looks like v9+ is going to be ViewComponents. That should be good enough for me :)
So, where - in the past - we used to build e.g. a contact form like this :
we now need :
Correct? Then how do we implement a Post-Redirect-Get scenario (e.g. https://andrewlock.net/post-redirect-get-using-tempdata-in-asp-net-core/) where - upon receiving an invalid Modelstate - we use ActionFilters to put the ModelState in tempdata, redirect back to the current page and fetch the ModelState from tempdata again?
Been trying, but ViewComponents don't have any filters and I'm really puzzled by this new approach.
Did you get any further with this?
I'm currently working on our first v9 site and like you I find it quite strange that there is the need for a ViewComponent and Controller to do something "simple" like a contact form.
Any update on this?
Using a viewcomponent to render the UI and controller to post feels weird.
normally I have the same as what Jeroen mentioned
1 HttpGET - to load the initial form data ( e.g. dropdowns etc.)
1 HttpPost - to send the information
how to achieve this with .net core
Do you find a solution for this ? :)
It does seem to work though it's a little awkward to set up: ViewComponent class that renders a view containing a form. The form submits to a SurfaceController class action.
When I add a ModelState error in the SurfaceController action and return CurrentUmbracoPage() it does render the form with the entered data and displays the ModelState errors.
But I did run into an issue. The form in the ViewComponent view has to be started with the Html.BeginUmbracoForm() helper. While you can use Tag Helpers to render the form fields, labels and validations you can't use the Form Tag Helper to render the form tag. A security header (or cookie)? is missing and the form won't submit.
I did run across this post where a guy builds a SurfaceController class that is also the ViewComponent ... thus marrying the two in one class.
https://www.programmingwithwolfgang.com/view-components-in-asp-net-core-mvc/
I haven't tried it myself yet but it might be worth looking into.
is working on a reply...