MVC vs Webforms: getting data from page to code behind - asp.net-mvc

Using webforms, a control can be defined like this:
<asp:label id="lblDate" runat="server"></asp:label>
and the code behind can manipulate it like this:
lblDate.Text = DateTime.Now.Year.ToString() + " eheheh";
lblDate.ToolTip = "tooltip";
lblDate.BackColor = Color.Red;
...
My question is: is there a similar way to manipulate a control in MVC?

MVC doesn't have server control; instead, it has HtmlHelper.
For example, the following Label Helper will generate the similar HTML mark up redered by WebForm's label control.
#Html.Label("Date", DateTime.Now.Year.ToString(),
new { style = "background-color: red", title="this is tooltip" })

The easiest thing will be for you to use JS or HTML tags while you can do it in the controller it is kinda pointless and too much work for basic properties you could use Ajax for that but like i said too much work. For Clearing textbox use JS. There are things like controls which are essentially JS libraries that have a corresponding .Net Libraries and you can build objects for the view and control them from Controller, usually those are for advanced and more rich features you add to your web site.

Related

Define something like for in ASP.NET MVC 3 to pass real html

How can define a custom block like #for in Razor view? I read about #helper here and here also there is a similar question here but #helper method just define html tags at first then when you want to use in views just can pass some parameters, in other hand #for block is that I want, in views you can pass Html (with intelligence support), Does any one have any idea about this? I also think about modify razor source code! (if possible) Is there any better way?
You may take a look at Razor Templated Delegates.

About coding style of MVC.net

I'm a control developer and I'm trying to design a MVC.net control. When I researched some of the MVC controls like MVC toolkit, Telerik and DevExpress etc, I'm confuse which coding style is the popular way.
For example, Telerik has its own special coding style, just like this sample:
[Code1]
Html.Telerik().Calendar()
.Name("Calendar")
.Value((DateTime)ViewData["selectedDate"])
.MinDate((DateTime)ViewData["minDate"])
.MaxDate((DateTime)ViewData["maxDate"])
It uses dot till the end. While the DevExpress allows us using lambda expression to setting so that we can write code in the View.
[Code2]
#Html.DevExpress().GridView(
settings =>
{
settings.Name = "gvSorting";
settings.CallbackRouteValues = new { Controller = "GridView", Action = "SortingPartial" };
settings.Width = Unit.Percentage(100);
settings.Columns.Add("ContactName").SortOrder = DevExpress.Data.ColumnSortOrder.Ascending;
settings.Columns.Add("CompanyName");
settings.Columns.Add("City");
settings.Columns.Add("Region");
settings.Columns.Add("Country");
}).Bind(Model).GetHtml()
Or another option is writing code in the Action and store it in the ViewData or Model, so that the [Code1] can be like:
Html.NewWay(Model).Render()
In this way, we can write all code in the action side. So maybe users are familiar with it.
I hope if you have any ideas or experience, please feel free to talk about it.
Thanks,
Howard
As you say, there are different ways to do it. It all depends on what you want to do.
The Telerik style is known as "Fluent" notation, it's designed so that every configuration entry returns the a reference to the newly configured object, and you must guarantee you will never return null.
There is no one overriding style, people like different ways. Do whatever you think works best for you.

Custom controls with ASP.NET MVC Razor

How can I use custom controls with ASPNET.MVC Razor?
I want to use a custom control on a Razor view. for instance:
<mycontrols:something>#Model.MyVar</mycontrols:something>
or
<mycontrols:something myattribute="#Model.MyVar" />
Please note that my goal is to use only few controls derived from MvcControl, only for trivial repetive ui stuffs.
I tried to find out a syntax similar to #Register to write on the top of the view, but without any success.
Then I went to the web.config, adding
<pages>
<controls>
<add tagPrefix="mycontrols" namespace="mynamespace" assembly="myassembly"/>
</controls>
</pages>
but it looks like custom controls are ignored in rendering.
Someone could help?
...Might be it is a little bit old fashion, but sometimes also custom control could be useful to make your code cleaner!
The Razor syntax does not support the notion of Controls at all. If you want to use controls you will have to use the ASPX (WebForms) syntax.
However, the recomended MVC pattern is to use html helper functions or partial views. In Razor you can also use the #helper syntax for quick helper functions.
In ASP.NET MVC custom server controls should be avoided. Most of them rely on ViewState and PostBack which are notions that no longer exist in MVC. You should prefer using templates, HTML helpers to implement some reusable functionality. Another problem with controls is most of them encapsulate some business logic which fetches data from somewhere and renders it which is an anti-MVC pattern. In MVC it is the controller responsibility to manipulate the model and fetch data and pass a view model to the view which simply should display it.
MVC uses partial views rather than custom controls, and they can be used in two ways that cover pretty much everything a custom control can do
RenderPartial which renders data already retrieved by the page controller
RenderAction which is similar but has its own controller action so can get data independently
The only scenario I can think of where it would be worth putting a custom control on an mvc view is if you are working on a partially migrated webforms project, and I doubt that would work with anything other than the WebFormsViewEngine.
You can do this, though I don't recommend it, though I'm not here to judge. I might add that I don't expect postback and view state to continue working either but you can at least render all of the html.
The only way to do this is a bit of a hack, because razor doesn't support webforms view engine controls. However, it does support partial views made in the webforms View engine. So a hacky solution is to include a partial view with your control in it as such:
For example, say you want to use the office web ui ribbon in your mvc3 project, you could do so by including
<body>
<div>
#Html.Partial("_RibbonPartial")
</div>
</body>
in your view. Where _Ribbon is of type .aspx
then in your partial view simply use your control and set runat="server" and put it inside of a form with runat="server"
//_Ribbon.aspx
<form id="form1" runat="server">
<XyzControls:Manager ID="Manager1" runat="server" UITheme="Silver" />
<XyzControls:OfficeRibbon ID="OfficeRibbon1" runat="server" ApplicationMenuColor="#267c29"
ApplicationMenuText="Item" ApplicationMenuType="Backstage">
//... rest of control code
</form>
Then you need to use ajax to implement events instead of using postback.
Then to cleanup, get rid of the generated code from webforms view engine for post back that you don't need.. You can try keeping it, I haven't so I'm not sure what will happen. I know there are ways to have a fake viewstate as well if you really want to get into messy hacky stuff, but to remove the extra code from webforms you can use the following jquery:
$(function ()
{
// we don't need any of the webforms stuff
$("#__EVENTTARGET","#aspnetForm").parents("div:first").remove();
$("#__EVENTVALIDATION","#aspnetForm").parents("div:first").remove();
});
I had the same demand. Wanted to use custom webcontrol from Razor/MVC page. One should not do that with controls, that is handling postback. You don't have the eventcycle to support that, but if your only demand is to use a 'rendering control', you could instantiate it in razor, and control where the rendering takes place:
#{
var myControl = new mycontrols.something();
myControl.myattribute = Model.MyVar;
mycontrol.RenderControl(new HtmlTextWriter(this.Output));
}

ASP.Net MVC: Creating custom controls kind of messy?

Main question: Is there a better way to accomplish creating a reusable control?
So the idea was to make a paging control to basically stop from having to keep typing out practically the same markup on multiple views. It's taking this:
<%= Html.ActionLink("First", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.FirstPage, amountToShow = Model.AmountToShow }))%>
|
<%= Html.ActionLink("Previous", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.PreviousPage, amountToShow = Model.AmountToShow }))%>
|
<%= Html.ActionLink("Next", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.NextPage, amountToShow = Model.AmountToShow }))%>
|
<%= Html.ActionLink("Last", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.LastPage, amountToShow = Model.AmountToShow }))%>
And turning it into this:
<%= Html.Pager("View", "Controller", "RouteName", Model, new Dictionary<String, Object> { {"parentForumId", Model.ParentForumId}}, " ") %>
Where as you can see I pass in the needed view, controller, route name, model, and a dictionary used to add request variables onto the url for the link.
What I found is that I would have to make an extension method for the HtmlHelper class and essentially take what in ASP.Net was a full class (with nice methods like CreateChildControls) and jam it all into one main method that returns a string.
Is this the preferred way of doing this? One nice thing of the ASP.Net way was markup to class as in you have the html markup tag that would translate markup properties to class properties. It generally made for cleaner mark up but admittedly "fake" html. In this situation I have a method with what could be a mile long signature pumping out html. And since I don't have a base WebControl class, every control I make will have to have method calls with the same basic needs like say CssClass or ID.
Now with that being said, I suppose I could pass in an attributes dictionary since the
HtmlHelper.GenerateRouteLink
method that I'm using calls for one anyhow, but this really seems really messy.
Is there a better way to do this?
First, its all ASP.NET...one is MVC, the other is WebForms. Took me a sec to realize what you were saying when you keept saying the "ASP.NET way". :P
The idea with an MVC is that your view is "dumb", without any real behavior outside of the absolute bare bones basics to render data. In WebForms, views were tightly bound to the behavior that rendered them and handled view events. This, while convenient, made WebForms views very difficult to unit test since view content and behavior were linked and sometimes blended.
The reason MVC views use things like HtmlHelper and AjaxHelper is to keep behavior as separated from the view as possible. Unlike a user or server control in WebForms, you can fully unit test an Html.Pager extension method, since the logic is pure code, without blending those UI concerns or being linked to a bunch of non-testable UI level types. The same general rule applies to MVC controllers to...they are just code, without being linked to events or anything like that.
It may be less convenient in the short run, as you are currently used to the old WebForms way of doing things. Give yourself some time, though, and you will likely start to realize the benefits that MVC's preferred way of doing things brings to the table. Writing a Pager extension method on HtmlHelper is indeed the preferred way to do things with MVC.
As for the mile-long signature bit...do a search (try out Bing.com!) for fluent style interfaces and HtmlHelper. The fluent style is starting to take a strong hold in environments like MVC views where you are likely to have huge signatures. The general idea is based on method chaining, kind of like jQuery, and can shorten those long signatures into a series of much shorter and more meaningful chained method calls that set up your html helper, with a final call to a .Render method or something similar.
You could put it in a partial view, instead of creating a helper.
You might want to check out Martijn Boland's Pager control for some inspiration.
Personally, for my reusable grid control I use a class that contains all information needed to generate a grid with paging, sorting, ... and I call partial views to generate the seperate elements (Pager, Column selection, pagesize selection, ...), passing the information they require to them.
This way I can easily extend the grid with custom stuff. For example I can create a Mygrid_editableTable.ascx view to show textboxes instead of just text, and add an extra column with a submit button. This while continuing to use the paging, page selection, ...
We end up using html helpers for paginators as they are easy to unit test. Pagination business requirements can be finicky.
"Show less than 35 links as numbers, then group by 20s unless there are more than 100 pages of results, in which case group by 100s...but on Thursdays, or to GoogleBot, show them as... etc."
Plus our SEO guys keep changing their mind on what shape urls get the most juice. In such a situation, something unit testable is a must!

Alternatives to server controls in MVC

What is the replacement for a server control in ASP.NET MVC? What I want to do is to create a declarative and imperative binding so I can write
<cc1:MyControl Header="Some Header" Content="Some Content" />
which would mean that an instance of the MyControl class will be created and possibly rendered to
<h1>Some Header</h1>
<p>Content</p>
I don't want any viewstate or postback crap, just the modularity. I also want these modules to be contained in a separate class library, so ViewUserControls will not do for me. Using a server controls in the normal way works, but it generates a form tag and a viewstate field, which I do not want if I can avoid it.
I have seen this question and this one about how to use server controls in ASP.NET MVC, but they do not provide enough answer.
Edit: I found the answer. When I added the user control using the designer, it automatically created a <form> which I missed. If I simply remove that tag, everything works perfectly.
You can still use all controls in ASP.NET MVC if they don't require rendering in a server form.
ascx files and #Register directives still work pretty well. The great new thing is Html.RenderPartial method that lets you pass a model object to a partial view (ascx) and have it render accordingly.
Just adding one more possibility to Mehrdad answer, you can use extension methods to do a simple control like this:
<%= html.MyControl( "Some header", "Some content" ) %>
<Extension()> _
Public Function MyControl(ByVal htmlHelper As HtmlHelper, _
ByVal Header As String, _
ByVal Content As String) As String
Dim sb As New StringBuilder()
sb.AppendFormat("<h1>{0}</h1>", Header)
sb.AppendFormat("<p>{0}</p>", Content)
Return sb.ToString()
End Function
Or you can make a more complex control like this example: Create an ASP.NET MVC GridView Helper Method
Other than the controls which still work with ASP.Net MVC, you can use mvc controls.
Repeater example - dead link
Exploring ASP.Net MVC Futures - dead link
UPDATE: This answer was for ASP.Net MVC 1.0 in 2009. It is outdated and irrelevant at this point.

Resources