After years of Web Forms development I've decided to give MVC a go. I've been able to work through most of the other stumbling blocks, but I'm kind of stuck on this one.
In Web Forms I would create controls for each of my forms in order to modularize so I could re-use them throughout my sites. I am attempting to do the same thing in MVC but with partial views and am not having much luck. It's probably something simple, and maybe I'm just not searching on the right set of keywords to find the obvious example.
Lets say I create a strongly typed partial view for a Login form. I want to include it on several pages of my site. Since the code is separate from the view, how do I encapsulate the logic so it can be easily reused in several views? In Web Forms, I just stuck it in the code-behind. In MVC do I have to put the code in every view controller where I want to use the control?
Second, how do you handle posts from partial views? I've tried creating strongly typed views and partial views, but the view models don't seem to populate automagically like they do when the form is directly on the view. I could always use the FormCollection as the action parameter and just force the values into my partial view models, but that doesn't seem too elegant. Can someone point me to some functional examples of how to use multiple strongly typed partial pages with forms on a single view (e.g. A login page with a login control and a register control)
In MVC you should not keep any logic in View(except View only bits).
For examples I suggest to look at Fabrikam Shipping.
To keep your Views DRY, you can use Partials and Edit/View templates.
To submit part of form - you can use jQuery AJAX(Hijax):
$("#someForm").submit(function () {
$.post($(this).attr("action"), $(this).serialize(),
function (response) {
$("#someContainer").append(response);
});
return false;
});
Also if you want to submit whole form to other action or controller, you can use something like this:
@using (Html.BeginForm("Action","Controller",FormMethod.Post,new{id="Form"}))
Place this in Views\Helpers
folder:
@helper LoginControl() {
@using (Html.BeginForm("Login","Home")) {
}
}
And use this in your views or the master:
<div>
@LoginControl()
</div>
now simply add this to your HomeController
public ActionResult Login(LoginModel model)
{
}
We don't have a really clean solution for Razor helpers in MVC3. In a regular web site, you can put a CSHTML or VBHTML file in App_Code and then use the syntax jgauffin suggested. Unfortunately, we weren't able to implement the ~/Views/Helpers model he mentioned due to some limitations in our compilation system we weren't able to overcome for v1 (we're investigating for v2).
David Ebbo, an architect on the ASP.Net team, came up with a solution that uses Visual Studio Code Generators so you can compile your helpers into ANY dll at all (even a regular class library): http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable-libraries.aspx. I highly recommend checking that out