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...
Related
I wish to replace the implementation of System.Web.Mvc.ActionMethodSelector as used by the FindAction method of ReflectedControllerDescriptor, but would like to take advantage of the existing implementation, ideally by deriving from ActionMethodSelector. However, because the class is marked as internal the only way I can see to do this 'properly' is to derive from ReflectedControllerDescriptor and implement FindAction by copying the code from ActionMethodSelector. I wish to avoid this however due to the quantity of code, and potential issues trying to keep it up to date with the framework.
I'm considering the following approaches:
Biting the bullet and copying the code
Using reflection so as to take advantage of the existing implementation
Are there any other approaches that I'm missing, better or otherwise?
I know it is a bit late to answer still I am giving it a try.... :)
I believe that you somehow want to tweak action method selection process in ASP.NET MVC. If my understanding is correct you can make use of custom ActionMethodSelectorAttribute by deriving from System.Web.Mvc.ActionMethodSelectorAttribute. Write your own custom logic in the custom selector and apply it on the top of the action methods. I believe in this way the action method selection process can be tweaked without disturbing the natural process.
If you wish you can visit these links: http://programersnotebook.blogspot.in/2014/02/aspnet-mvc-actionnameselector-and.html, http://programersnotebook.blogspot.in/2014/02/aspnet-mvc-actionnameselector-and_2.html
When would be the bean tag used in struts.xml configuration file using Struts 2? What is difference between action class properties and bean tag in Struts 2 configuration file struts.xml?
Some places have strict separation of work or for what ever reason you can edit the view (JSP) but not the actions source.
In this case the bean tag becomes most useful (otherwise I agree it isn't particularly attractive). It is generally easiest to produce what is needed for the view within the action and also process that data such that it is readily displayable. As such there is not generally much need for append, generator, merge tags either... but once again if you consider the content people separate from the backend people these tags would be used more often.
In theory it is possible to use the bean tag to access things like singletons for counters and such, but if the view is acquiring resources in this way it is kind of a component way of thinking(as opposed to action based thinking). This is also why the action tag's use isn't particularly favored either. If you need it, the action class should be the main one responsible for getting it (or interceptors, but certainly not the view) at least following action based thinking.
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.
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 would like to know if it is possible, in Struts2, to map an HTML form's fields to those of an action, automatically, without getters and setters.
It is clear that by getters and setters or the ParameterAware interface and the Map, fields can be set in the action, but I just wanted to know if otherwise there was a way.
First, instead of thinking in terms of "with fields with getters and setters" you are advised to think in terms of "bean properties" here. Struts2 (and most java frameworks) think in that way, they usually don't care (and rightly so) whether those "properties" are real fields or not.
The short answer to your question is: no.
But be aware that Struts2 is very flexible - when I say "no" I mean "using the default interceptors". You could always write your own interceptor instead of the default to do that - bad idea IMO.
The interceptor that does that mapping is (basically) the parameters interceptor. From its documentation:
This interceptor gets all parameters
from ActionContext#getParameters() and
sets them on the value stack by
calling ValueStack#setValue(String, Object)
typically resulting in the values
submitted in a form request being
applied to an action in the value
stack.
And looking into ValueStack.setValue(String,Object) we read:
Attempts to set a property on a
bean in the stack with the given
expression using the default search
order.
So there you have.
ModelDriven was the correct choice :)