ASP.NET MVC: For Those Who Dislike Reusability
-
Mvc resusable controles are not dependent on ajax. Use uihint attribute over the property on which the control is to be rendered. In uihint pass the partial view name. In view page use editorfor to render that property. The partial view will be rendered automaticaly. The property will act as model to that partial view so make sure the datatype of the property and the model of the view is same.
MVC controls are reusable so long as they don't require a postback (e.g., a submit button). That's the tricky bit.
-
Have you looked at the helper method called @HTML.Action("ActionName", "ControllerName")? You can embed those on your _Layout (i.e. master) page as well as other views. It doesn't change the URL and allows you to grab data it its own controller separately from the host page. I use it with good success.
-Brian Hall-
I don't think that would help with a postback.
-
I'm going to throw this into the ring and see where it lands, so no thrashing. I'm just now doing heavy research on MVC3 as well. And I'm very interested in re-usable controls in MVC. That is how we currently do it in web forms. BUT, the control is linked to the parent page through events. For example, I click "Save" on the control, and it fires an event that is registered on the parent, to execute a method and in the method it basically fire the "Save" method on the control, plus whatever actions it needs to do (hide panels, display things, whatever) on the parent. ANYHOO, is there no way to register events like this between Views? Or is that the AJAX part everyone keeps mentioning? Personally, I agree with the OP and tend to avoid JavaScript whenever possible because the user can turn it off, and then you have a failed app.
EngleA wrote:
ANYHOO, is there no way to register events like this between Views?
One might be able to build something (e.g., have buttons submit a particular value and each "control"/partial view would look for that value in the request and would call a method accordingly), but there's nothing built-in to MVC to handle that. Not to mention that seems to bind the views and controllers a bit too closely.
-
EngleA wrote:
ANYHOO, is there no way to register events like this between Views?
One might be able to build something (e.g., have buttons submit a particular value and each "control"/partial view would look for that value in the request and would call a method accordingly), but there's nothing built-in to MVC to handle that. Not to mention that seems to bind the views and controllers a bit too closely.
And that's why I believe MVC3 is just not...enterprise ready. It's great for a personal blog or a music store (as long as no purchases are being made), but for an enterprise environment with business models and whatnot... I'll stick with ASP.NET and all it's random "clunkyness" because at least my code is re-usable, and I can link it up with WCF services and other products. :-D
-
Not exactly. You see, the reusability can be created only with the help of AJAX. In web forms, my user control need not rely on AJAX to be reusable. In MVC, the user control would simply fail completely without AJAX. Though, it's not too much to expect for a user to have JavaScript, so that's probably the route I'll take.
It seems that JavaScript is required for most web frameworks nowadays. In my opinion, that's a good thing. It makes a lot more sense for controls to work this way, and the overall behaviour of a page seems to be a lot more in the developer's control than with the old model.
-
OK, deliberately polemic/provocative title ;) . ASP.NET is really a semi-coercion of Winforms type development into a web context. Quite often it fights the web paradigm and hides stuff from the developer, in some cases this is a good thing, but in others it isn't. I know I've learnt more about the web part of web development more in the few months I've been using MVC3 than in a good few years of ASP.NET "Forms".
AspDotNetDev wrote:
After reading an 800-page book on MVC and just now starting to get my hands dirty, I still have seen no clear way to make reusable user controls in MVC.
My emphasis is important here. We've just spent the last x years (in my case 10, on and off) in the same way of working: "winforms" (For want of a better way of putting it) but across a client server architecture. MVC3 requires time to get to grips with, it is a different way of working (and much more harmoniously with http). Obviously the learning curve is there, and you'll spend a lot of time thinking in ASP.NET "Forms" I could just do x,y or z. Obviously this is because you've got the x years experience in ASP.NET, but less than one in MVC3. I know this as I had exactly the same thoughts when I started using MVC3 last summer. Now I prefer it for sites that aren't just "Winforms type Web apps", and even on those I'm increasingly 50:50 about. I seriously suggest you spend the time to get to know MVC3 Properly, I think it is really fantastic, when applied to the correct things. To look at your specific point about controls, let's say you want to create the Equivalent of an "Address Control": 1. Use the MVVM pattern, don't try and bind the business model directly unless it is a very good fit. The idea is to "bind" the [View]Model to the UI, by providing templates Dependency Injection becomes a breeze too. 2. Create an
AddressViewModel
class and any converters from the business model you want. 3. In the relevant folder (possibly views/shared) Create two folders "DisplayTemplates" and "EditorTemplates". These must be called this by convention to these add your markup in files calledAddress.cshtml
(assuming razor view engine). 4. Let's suppose you put the Address object you want to display in a parent View-Modelunder the a property calledCustomerAddress
. 5. Where you want to display the Address you just put@Html.DisplayFor(model => model.CustomerAddress)
editing is pretty much the same:Keith Barrow wrote:
Now I've used it for a few months, the thing that I find most objectionable about MVC3 is the amount of "Magic" that happens. A lot of stuff "just works" due to the reliance on convention and it feels like a chicken has been sacrificed and its bones cast to achieve it (The "postback" being "bound" the ViewModel in the example above, or individual form elements "just work" ).
Amen! I felt the same way after finishing the MVC Music Store Tutorial[^]. I'm starting to work through the book Professional ASP.NET MVC 3 from Wrox and I also have Programming Microsoft ASP.NET MVC 2nd Edition from Microsoft Press. I feel a bit lost still, but I think I'm starting to wrap my brain around the concepts... somewhat.... :-\ A 5 for the post. It's very informative. I'm sure I'll have a ton of questions as I go. Flynn
_If we can't corrupt the youth of today,
the adults of tomorrow will be no fun...
_ -
Sorry, that does not really help. Suppose one of those controllers (e.g., ChatController) needs to accept a postback when the user clicks a submit button (e.g., a "Send" button to send a message) and that the user does not have JavaScript. Which action method would you recommend that postback go to and what ActionResult would you suggest it return? And keep in mind that I don't want the URL to change and I don't want the page layout to be different when the response is sent back to the client.
-
dave.dolan wrote:
The url doesn't change.
Yes it does. Here, I'll give you an example. Suppose I create a new MVC 3 Internet project and delete most of the files. The remaining (important) files/folders are this:
- Controllers
- AccountController.cs
- HomeController.cs
- Models
- AccountModels.cs
- Views
- Account
- LogOn.cshtml
- Home
- Index.cshtml
- Shared
- _LogOnPartial.cshtml
- Account
- Global.asax.cs
Here are the contents of each file (minus namespace stuff):
// AccountController.cs
public class AccountController : Controller
{
[HttpPost]
public ActionResult LogOn(LogOnModel model)
{
return View(model);
}
}// HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}// AccountModels.cs
public class LogOnModel
{
[Display(Name = "User name")]
public string UserName { get; set; }
}@model MvcApplication6.Models.LogOnModel
I am LogOn.cshtml@{
Layout = "";
}
<html>
<head><title>I am Index.cshtml</title></head>
<body>
@Html.Partial("_LogOnPartial")
</body>
</html><!-- _LogOnPartial.cshtml -->
@model MvcApplication6.Models.LogOnModel@using (Html.BeginForm("LogOn", "Account"))
{
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
<input type="submit" value="Log On" />
}// Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
RouteTable.Routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}Click the "Log On" button and you will be redirected from http://localhost:56736/ to http://localhost:56736/Account/LogOn (the port will be di
I see what you mean now about the redirect now. I have used MVC on many projects since 1.0 but they've all been either windows auth or no-auth so I hadn't noticed. (I know that's a red flag right there, someone just said 'enterprise.' After having my arse handed to me above I think I might deserve it.)
AspDotNetDev wrote:
So then, what haven't I figured out that you have?
That was not directed to you. I know I shouldn't mash it in with a reply to you. I generally regard you as a very intelligent person and I respect your posts. Sometimes I get carried away. (But you did too in the OP title. :P)
- Controllers
-
I see what you mean now about the redirect now. I have used MVC on many projects since 1.0 but they've all been either windows auth or no-auth so I hadn't noticed. (I know that's a red flag right there, someone just said 'enterprise.' After having my arse handed to me above I think I might deserve it.)
AspDotNetDev wrote:
So then, what haven't I figured out that you have?
That was not directed to you. I know I shouldn't mash it in with a reply to you. I generally regard you as a very intelligent person and I respect your posts. Sometimes I get carried away. (But you did too in the OP title. :P)
dave.dolan wrote:
But you did too in the OP title
The Lounge has been pretty boring lately. Thought I'd spice things up a bit. :rolleyes:
-
After reading an 800-page book on MVC and just now starting to get my hands dirty, I still have seen no clear way to make reusable user controls in MVC. Sure, one can create a partial view and use some AJAX so that the view can update itself by calling the appropriate controller/action. But if the user doesn't have JavaScript enabled, they're screwed. And I could pass around the main view name to the partial view, but then I'm either passing more details than I'd like to the client or I'm using session, which is best to avoid in a server farm situation (not to mention instantiating the proper model could prove troublesome). And I could have the partial view post to an action method on the parent view's controller, but then I have to do that for every page that makes use of the partial view. What a nightmare. I think I'll go back to ASP.NET web forms. :|
Imo this style of doing webapps is so yesterday. Use something like qooxdoo, ext, smartclient or sproutcore for the UI (all of which are great at letting you build reusable controls), and build your server-side app so it only supports stateless JSON-RPC requests. You trade some startup latency for almost no session info (you usually still have to keep auth info in the session, but that's about it - and you can consider it immutable, usually), lower bandwidth requirements and much lower latency. Plus, switching from one backend to another is a lot easier - presentation is separated at protocol level instead of API level, and there's no presentation code in your server app. And you get a services interface to your app for free - it's not just your web UI who can call the JSON-RPC services.