What is the use of Html.BeginForm in MVC3.
Why do we use it, when we can just add a form tag directly, does this html helper add some capability or does something which cannot be done with a simple form tag.
The Html.BeginForm helper method contains a couple overloads whose intended purpose is to make writing routed forms easier. It is aware of MVC stucture and makes sure its targeting a controller and action. It's just a bit of syntactic sugar over:
<form method="post" action="#Url.Action(...)">
In Microsoft's words:
The ASP.NET MVC framework includes helper methods that provide an easy way to render HTML in a view.
Of course, no one is making you use them. Its just a matter of preference. In fact, in the early days of MVC, many WebForms developers celebrated their new freedom from server controls a-la <asp:TextBox> et al., and insisted on writing everything by hand.
Using the helpers for your form fields comes highly recommended, since they're aware of things like form validation. Html.BeginForm just gives you a consistent way to start and finish your form:
#using(Html.BeginForm())
{
#Html.LabelFor(...)
#Html.EditorFor(...)
}
Html.BeginForm returns an IDisposable object, allowing you to wrap it in the C# using statement. When the using exits, the disposal will call Html.EndForm() automatically for you. Since Html.EndForm returns void it is slightly inconvenient to call from Razor:
#Html.BeginForm()
<formStuff>
#{Html.EndForm();}
A simple #Html.EndForm() will turn in to Write(Html.EndForm()) -> Write(void), ie compile time error.
Of course you can code it by hand, but it does have several advantages, such as:
it returns an object that is disposable, so that you can put it in a using clause and it will close the form tag for you
it computes the URL for the form action
does something which cannot be done with a simple form
At the end every helper method call is converted to pure HTML so there is nothing that Html.BeginForm can do that can't be done by using the <form> tag directly.
Html.BeginForm is purely an helper method.
What's the purpose of having helpers at all? (Rhetorical question) You could type all inputs manually as well, but helpers... well, help you sometimes.
all it does it put tag. Yes, you can do it manually, or you can be a bit more fancy and do this:
#using(Html.BeginForm())
{
}
This will close the form tag for you as well. So if you keep all your inputs inside the curvy brackets, you don't need to worry about remembering closing the form tag.
Excellent question, I wondered about that myself quite a bit.
I could be wrong, but here's my guess (a better man may correct me):
In the early days of MVC, there was no razor.
Switching between C#/VB and html was hard syntax-wise, so there was a push towards minimizing those borders.
When creating forms, it was seen beneficial to create the entire form purely on the C#/VB side, without any intermingling manual html, to just have one border to the surrounding world of html.
And since programmers often copy the style of doing things from somewhere else, the practice of using those helpers has persisted even though their benefit has disappeared with the advent of razor.
Related
Is the following snippet a good practice when using Knockout components + Asp.Net MVC? Any drawbacks I am maybe missing?
Is basically injecting part of the ko component dependencies (mainly initial data) by using Razor server side rendering...
Code snippet:
<my-component params="{
foo: '#Model.FooProperty',
bar: '#Model.BarProperty',
baz: #Json.Encode(#Model.SomeArray)
}"> </my-component>
EDIT:
For avoiding the string escape issues pointed by #Quango, I've implemented this helper:
public static stringEscapeString(this HtmlHelper helper, string value)
{
return HttpUtility.JavaScriptStringEncode(value, true);
}
Usage:
<my-component params="{
foo: '#Html.EscapeString(Model.FooString)', ...
We use Knockout in an ASP.NET MVC project at my job, and do consider this bad practise. But the reasons for this might not apply to you. This is something you'll have to judge for yourself
No caching of HTML (since the injected values might change)
No bundling of your HTML with your JavaScript (same as above)
Mixing different solutions for the same problem can be a bad practise, especially in (large) teams. Essentially, you've picked Knockout, so the 'normal' practise would be to acquire any data you need in JavaScript, and bind to it in your view. If this is what you usually do, consider if you really want to create an exception here, just because the data is (supposedly) static. If this is all about saving a few bytes, then just imagine balancing this out to serving ALL your HTML and JavaScript in a minified bundle, that can also be cached on the client.
No way to override the data later, it is essentially 'hard coded' by the server.
Your code becomes less portable. Your Razor syntax essentially couples your frontend to your chosen backend technology. If this is a long term project, consider if there might be a small chance that in a couple years from now, you might decide another backend technology might be a better alternative, and if it really makes sense that you'd have to rewrite half the frontend just to make this possible.
None of these reasons are relevant for ALL projects, so it depends a lot on the context. I've tried to list as many possible disadvantages as I could think of.
I need to use Struts2 <s:if> Tag to evaluate a function return value from different JSP pages.
The function is implemented inside a Class, and I want to use it in different JSP pages
Example:
<s:if test="%isLogin()==true">dosomething</s:if>
<s:if test="%{isLogin()}">dosomething</s:if>
Or better yet:
<s:if test="%{loggedIn}">doSomething</s:if>
Naming matters.
Don't fight the framework and Know your libraries.
Stop a minute and learn how it works. Then you will probably have no need to change its behavior anymore, but if you will, you will know how to do it in the right way.
If something is common to a lot of Action / JSP AND it is VIEW stuff (like providing data that must be drawn on every page), then put it in a BaseAction and extend it from the other actions.
If something is common to a lot of Action / JSP AND it is BUSINESS stuff (like checking if the user is logged in or not), do it serverside, with an an Interceptor.
Never put logic in JSP, the JSP must not even be reached in that cases.
Some useful readings are:
Introducing Interceptors
Interceptors
OGNL
OGNL Language guide
But I suggest a deep dive in the whole Struts2 documentation... you will get better code and will save a lot of time after few days...
I am building my first mvc3 app. A few questions I have are:
1) the razor view engine lets me embed code into the views. Is this not what we were once trying to get away? ie keep code out of the aspx.
2) Do models need to implement an interface?
3) Do models need to have methods? Or just properties?
Thanks
Pretty vague question, but I'll give you my 5c worth:
True, but the code we put in the Razor views are usually only to generate Html-controls.. the helper methods in MVC3 utilizes data attributes from your Viewmodels and generates validation etc.
When that is said, it's completely optional how much code you wish to put in your views.
No.
Viewmodels should be as stupid (POCO) as possible, and business logic method should be put on your domain models, as the good DDD developer you are ;)
The code that you put in the view is supposed to be rendering code only. Simple for loops for repetition, calls to EditorFor or DisplayFor or stuff like using (Html.BeginForm()). The main business logic should never be placed in the View layer.
No.
No, just properties. You can add really simple helper methods, but the important stuff is the properties, so even the helper stuff should be implemented as readonly properties.
Actually, the first part is true for the aspx engine and WebForms as well. And Php, and classic ASP, and...
1) It may seem a bit like that, but really it depends what the code is. IMHO You should really avoid any logic or code in the view, other than that directly related to rendering the view. For this code though, Razor gives a lovely clean way of coding in the view.
2) No - any class can be a model.
3) There is nothing to stop you putting methods on the model - but really they should be very simple data tranfer objects - they just "carry" data around. So more often than not, stick to properties.
1) the razor view engine lets me embed code into the views. Is this not what we were once trying to get away? ie keep code out of the aspx.
No, we were once trying to get the logic out of the view. This gives a bit more control over the view, but should not be used as a method of implementing logic.
2) Do models need to implement an interface?
Nope.
3) Do models need to have methods? Or just properties?
Models are just classes. They define the structure of your class.
What areas get affected by it?
code readability? maintainability? performance? security? any other?
my views have been using something like
if(Model.Showthis) {<div id = "showthis">...</div>} }
and does doing something like the following have security implications? --
<%if (HttpContext.Current.User.Identity.IsAuthenticated && item.Poster.UserName == HttpContext.Current.User.Identity.Name)%>
<%{%>
...
<%}%>
yes I read "if" considered harmful in ASP.NET MVC View (.aspx) files? too, but it didn't exactly specify what areas get affected by it. I mean I wanted to make sure there are no security and performance implications, which the link didn't answer exactly
I think the stigma persists from the transition from ASP to ASP.NET Forms. MVC is a different beast. With MVC3 and Razor it should help break the stigma and allow for more readable, easier to write Views.
That said, Domain and Business logic should never be in your template. But I see no problem, and frequently make use of conditional statements and loops to render UI in my Views.
I don't see an issue with it as long as the branching logic is purely for UI concerns. With that in mind I would change your second if to:
<%if (item.Poster.UserName == Model.CurrentUserName)%>
<%{%>
...
<%}%>
And set your model up so that the CurrentUserName property looks like this:
public string CurrentUserName
{
get
{
return HttpContext.Current.User.Identity.IsAuthenticated
? HttpContext.Current.User.Identity.Name
: String.Empty;
}
}
Or even better if you're going to be checking author against current user a lot in your system, offload that property to a helper class that can be reused from multiple models. Basically I wanted to get the implementation detail of what the current user's name is out of the view.
There's nothing wrong with if else statements in your view template. What you want to avoid is business or model logic in side your view template. If the conditional is directly related to user interface, then it belongs in the view.
Yes, it can be a bit difficult to read because of the mix of HTML and C#, but so long as your view logic is in your view, and your model logic is in your model, you are properly maintaining separation of concerns.
With your second sample; it might make more sense to only have your Poster available to the View if the correct user is logged in in the first place; this seems like more of a Controller thing than a View thing to me.
A lot of people see if statements in the View and cringe, because it reminds them of classic ASP. But the problem with classic ASP was never that there was code and HTML in the same place; it was that there was business logic and presentation logic in the same place.
Edit Also, perhaps duplicate of "if" considered harmful in ASP.NET MVC View (.aspx) files?.
Why are they bad?
As many people have already suggested it's because it can be a warning sign that business logic is leaking into your views which is a bad thing. Or that you are trying to do too much in your view. Often it's easier to setup the necessary data in your controller and just pass everything required (including any computed values) and have your view render it straight out. The flatter and simpler your view model is the better.
I don't think there is anything wrong with using if/else's for the true purpose of conditionally rendering UI. For example, if a user is logged in render this partial if they aren't than render something else.
I think a lot people get taken back and draw a hard and fast 'it's bad practice' because it can easily lead to tag soup. This phenomena has already been highlighted as a carry over from the asp.net webforms engine. Whilst still a good thing to be aware of, it is likely less of an issue with the razor engine as it's much cleaner and requires less syntax to achieve the same thing. The automatic switching in and out of C#/VB code to html and back is very simple with only an # required to re-enter a code block. I don't think this will create tag soup in the same way that angled brackets did <% %>. The amount of noise in the latter was what most people objected to (and rightly so).
Lastly, circumstances depending, if you find you are starting to get a lot of if/else logic in your view sometimes it is cleaner to put that into a HTML helper. I can't find the reference but I remember Rob Connery once saying that if you find yourself starting to write if statements in your view than it's a candidate for a html helper.
Is there performance of security concerns?
I don't think there is going to be any noticable performance differences or security concerns with what you are asking. But considering an authentication check like that is likely to be used in multiple views I would put it into a Html helper.
If-else blocks are not bad specifically. Code in views is bad because you are mixing HTML markup with code. ASP.NET MVC is bad for separating static page design from dynamic UI code. Web Forms is better at separating static and programmatic UI elements.
I am trying to refactor my views a bit and up til now i have been using the built HTML helpers but i thought i would create my own - they're extension methods right?
I wonder if anyone can confirm or give advise when an HTML is needed? I think i once saw a document that said if you use 1 IF statement in your views encapsulate it into a html helper - would anyone agree with that?
With regards to creating html helpers, would it be better to create my own class rather than add extension methods to the HTML class that ships with MVC? Any body have ideas on this?
Or possible i shouldn't bother with HTML helpers and just use the built in ones and continue to use my IF statements within views.
Thanks in advance
Use HTML helpers when you want to encapsulate the output of a piece of HTML markup that can take varying values.
I'd recommend creating them as extension methods to HtmlHelper rather than creating your own class, as your own class won't be available inside of the default ViewPage without either instantiating a new instance inside of the View or subclassing ViewPage and using this in the View (or passing in on the model, but that's just wrong!).
HTML Helpers are extension methods. I can confirm as well that I too use the 'if' rule when it comes to views. Any view logic coded should, IMO, be in a helper.
You can use helper to render custom markup, or control which markup(ie existing view) is displayed.
Not too sure about the ease of this, but it does lend itself to more unit testing (please comment on this aspect if someone has more info).
With regards to creating html helpers, would it be better to create my own class rather than add extension methods to the HTML class that ships with MVC? Any body have ideas on this?
If I understand correctly, in this respect my suggestion would to separate your helpers into their own classes. The reasoning behind this for me would be that you easily know when looking at your views what are standard helpers vs the ones you've created. I think this will improve maintainability.
i shouldn't bother with HTML helpers and just use the built in ones and continue to use my IF statements within views.
I'd say No! (or it depends). One of the benefits of using a helper would be to reuse the same view logic in multiple views as opposed to re-coding the same if statements. This means your code is more DRY, which is always better. In the event you need to debug some weirdness error, you only need to look in one place, the newly created helper.