Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bo Damgaard Mortensen 712 posts 1189 karma points
    Oct 28, 2014 @ 12:51
    Bo Damgaard Mortensen
    1

    MVC strongly typed views and forms

    Hi all,

    For the past six months I've been away from Umbraco doing AngularJS projects and now I find myself doing a rather large Umbraco (7) MVC project with a lot of forms manipulating data in a custom (non-Umbraco related) database.

    I can't for the life of me remember how I go about doing forms in Umbraco MVC, though. At the moment I have all my views as strongly typed views with corresponding controllers which inherits from the RenderMvcConroller.

    As far as I remember, you'll need to use SurfaceControllers to do postbacks w. forms etc, but I can't seem to grasp how it all fits together.

    As an example, I have a view which should display a table with log items from the database. My view looks like this:

    @model mynamespace.ViewModels.AdminLogViewModel
    
    <div class="container">
        <div class="row">
            <div class="span1">
                @Html.Label("S√łgekriterier:")
            </div>
            @Html.Action("RenderLogForm", "AdminLogSurface")
        </div>
        <div class="row">
            <div class="col-md-12">
                @if (Model.LogItems != null)
                {
                    <table class="table">
                        <tr>
                            <th>Tid</th>
                            <th>Bruger</th>
                            <th>Besked</th>
                            <th>Niveau</th>
                        </tr>
    
                        @foreach (var logItem in Model.LogItems)
                        {
                            <tr>
                                <td>@logItem.Date.ToString("dd-MM-yyyy hh:mm:ss")</td>
                                <td>@logItem.Username</td>
                                <td>@logItem.Message</td>
                                <td>@logItem.Level</td>
                            </tr>
                        }
                    </table>
                }
            </div>
        </div>
    </div>
    

    And my controller for this view looks like this:

    public class AdminLogPageController : MasterController
        {
            private ILogRepository _logRepository;
    
            public AdminLogPageController(ILogRepository logRepository)
            {
                _logRepository = logRepository;
            }
    
            public ActionResult AdminLogPage()
            {
                return View(AdministrationMapper.MapAdminLogPage(CurrentPage, new AdminLogViewModel(), new LogRepository()));
            }
        }
    

    (inheriting from the MasterController which looks like this)

    public class MasterController : RenderMvcController
    {
        protected ViewResult View(MasterViewModel model)
        {
            return View(null, model);
        }
    
        protected ViewResult View(string view, MasterViewModel model)
        {
            return base.View(view, MasterMapper.Map(CurrentPage, model, new UmbracoHelper(UmbracoContext.Current)));
        }
    }
    

    Now, the form needs to have several filter options, i.e. a searchfield, a log level dropdown filer etc.

    In my AdminLogSurfaceConroller I have the following code:

    public class AdminLogSurfaceController : SurfaceController
        {
            private ILogRepository _logRepository;
    
            public AdminLogSurfaceController(ILogRepository logRepository)
            {
                _logRepository = logRepository;
            }
    
            public ActionResult RenderLogForm(AdminLogViewModel viewModel)
            {
                return PartialView("LogForm", viewModel);
            }
    
            [HttpPost]
            public ActionResult SearchLogs(AdminLogViewModel viewModel)
            {
                // This is where I'm stuck..
                viewModel.LogItems = _logRepository.FilterLogItems(viewModel.LogSearchViewModel.FilterDate,
                    viewModel.LogSearchViewModel.FilterUserName, viewModel.LogSearchViewModel.FilterMessageText,
                    viewModel.LogSearchViewModel.FilterLogLevel, 0, 200);
    
                return View("AdminLogPage", viewModel);
            }
        }
    

    I have an odd feeling that this is fundamentally "wrong" when you have an MVC site with a lot of forms on it. I.e. I shouldn't make use of the controllers that inherits from the RenderMvcConroller class.

    Question is, how would you make a table with a form to filter and search the records? I'm honestly a wee bit lost on this one ;-)

    Thanks in advance!

  • Andy Butland 364 posts 1983 karma points MVP 4x c-trib
    Oct 28, 2014 @ 14:50
    Andy Butland
    3

    I think it's broadly OK Bo.  There are two key base controllers in Umbraco - RenderMvcController and SurfaceController.  You inherit from the former for route hijacking and the latter for generating partials and handling form posts.  That's perfectly fine I feel and for some would quite like this approach as it arguably gives you better separation of concerns.

    For me though I took a lead from the Hybrid Framework package that Jeroen put togther.  Which is to have my base controller inherit from SurfaceController but implement IRenderMvcController.  See the SurfaceRenderMvcController base class.  That way you can have one controller per document type, that willl handle both your route hijacking and your form partials and processing.  

    Hope that helps.

    Andy

  • Danny Blatant 91 posts 358 karma points
    Oct 28, 2014 @ 19:11
    Danny Blatant
    0

    Unrelated, but thanks Andy! (Rep to you!!!) That explanation of the SurfaceRenderMvcController is basically the missing link to my understanding of how the Hybrid Controllers work, thansk for the brain nugget!

    Danny "Blatant"

  • Bo Damgaard Mortensen 712 posts 1189 karma points
    Oct 30, 2014 @ 19:33
    Bo Damgaard Mortensen
    0

    Hiya Andy,

    Thank you so much for your answer - and I'm sorry I couldn't get back to you sooner. It's been quite a week ;-)

    I too thought that my apporech was clean and more 'real' MVC. I've used it for the past 6 - 8 projects or so, but all of these had either Contour installed or I've made AJAX forms. This particular project needs to have a lot of regular forms, manipulating external data (data stored outside of Umbraco's database), so it wasn't really an option to make use of route highjacking this time. At least not in my point of view.

    We considered the Hybrid framework (thanks for an awesome package, Jeroen!, you rock!), but finally went with "just" using partial views with surface controllers. Makes for a bit more work by creating a partial view for each view, but it actually seems to work quite nice and it still feels very MVC (the regular way, that is)

    For another project, I'll definitely dig deeper into the Hybrid Framework, though. It seems like the most clean way :-)

    Thanks again !

Please Sign in or register to post replies

Write your reply to:

Draft