Call another portlet from renderMapping - spring-mvc

I want to call another portlet from renderMapping of one portlet. How can i do it. Code snippet is as follows:
Portlet 1:
#RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, Model model) {
if(!admin){
return "index"
}
else{
//i have to call the rendermapping method of Portlet 2 and need to redirect to portlet 2
}
}
How can i call the portlet 2 .

For maintainability reasons you shouldn't. If both use common code, extract it into a common implementation that both call into. That's the proper way of code reuse. If both portlets are in the same plugin, there will also be no classloading issue and this is a very easy option. Everything else (calling the render method of a totally different portlet) is not your business - leave it purely to the portlet container and don't go there yourself.

As far as I know, you can't. There's a reason why the portlet lifecycle has two phases, the ACTION and the RENDER phase.
If you want to redirect to another portlet, you'll have to use the action phase, so you'll need to create an action URL which can be clicked on, in the action phase you can do something like this:
#ActionMapping("goToDetail")
public void goToDetail(#RequestParam(value = "id") Long id, ActionRequest request, ActionResponse response){
response.setEvent("detailTask", id);
}
In this action phase we set an event, which triggers the portlet wires, so you'll have to configure those properly in your portlet.xml (supported publishing/processing events) and then you probably have to configure something on Liferay as well.

Related

Is a centralized processing of request header data possible?

Let me explain what my problem is:
In a Web API project I am facing the issue that every single request which is sent to my controller has to contain some header data which should be processed before the controller action runs.
So as far as I know, I could include a new argument on every single action and decorate it with a FromHeader Attribute. Currently there are about 2000 actions from several controllers where I would have to change the parameter signature. So it would be a much prettier solution, if I could centralize the processing of this header data.
I am looking for some code to overwrite which is between the constructor of the controller class and the execution of the controller's action. Does anybody know a method for overriding or a pattern to accomplish this requirement? May be there is a possibility to extend the routing to the action
public override void OnActionExecuting(ActionExecutingContext context)
{
/*
PUT YOUR CODE HERE ;-)
*/
base.OnActionExecuting(context);
}

ASP.NET Web API - method that is called for all requests prior to the routed method?

I'm writing in C# for ASP.NET Web API 2. What I want is a catch-all method that will execute for every single request that comes to my Web API.
If the method returns null, then the original routing should continue, seeking out the correct method. However, if the method returns, say, an HTTPResponseMessage, the server should return that response and not proceed on to normal routing.
The use case would be the ability to handle various scenarios that may impact the entire API. For example: ban a single IP address, block (or whitelist) certain user agents, deal with API call counting (e.g. someone can only make X requests to any API method in Y minutes).
The only way I can imagine to do this right now is to literally include a method call in each and every new method I write for my API. For example,
[HttpGet]
public HttpResponseMessage myNewMethod()
{
// I want to avoid having to do this in every single method.
var check = methodThatEitherReturnsResponseOrNull(Request);
if (check != null) return (HttpResponseMessage)check;
// The method returned null so we go ahead with normal processing.
...
}
Is there some way to accomplish this in routing?
This is what Action Filters are for. These are Attributes that you can place either globally, at the class (Controller), or at the method (Action) levels. These attributes can do preprocessing where you execute some code before your action executes or post processing where you execute code after the action executes.
When using pre processing you have the option to return a result to the caller and not have your method (action) be fired at all. This is good for model validation, authorization checks, etc.
To register a filter globally edit the WebApiConfig.cs file.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new YourFilterAttribute()); // add record
// rest of code
}
}
To create a custom attribute inherit from System.Web.Http.Filters.ActionFilterAttribute or you can implement interface System.Web.Http.Filters.IActionFilter or you can implement IAuthorizationFilter/AuthorizationFilterAttribute if you specifically want to allow/deny a request.
It also sounds like you want to create multiple attributes, one for each role like IP filtering or count calling etc. That way it would be more modular instead of one enormous authorization filter.
There are many tutorials out there like this one (chosen at random in my Google search results). I am not going to post code because you did not do so either so I would just be guessing as to what you wanted to do.

MVC4 - Relationship between a View and a Controller

I'm having difficulty grasping the concept of MVC within .NET. I'm creating a basic Blog application, mainly to gain insight and skills with MVC. I just don't quite get some of it. The part I am currently unclear about is the relationship between a Controller and View. It would clear the matter up if someone would answer me this.
I have a View called TestA which corresponds to my Controller ControllerTestA. Now I've added the following inside the ControllerTestA.
public ActionResult TestA (){ //do something }
Now I need to know if all my postbacks in whatever form from view TestA will have to go through my TestA Controller method. So essentially I could have different postback with different parameters for different reasons. Some in use with one postback and others in use for another. Is that how it is done?
Would love some assistance here.
You are missing a crucial part of the relationship here, which is routing. You are speaking in terms of WebForms using terms like Postback; don't do that because you'll end up confusing yourself.
The best way to think about MVC is in Requests and Responses.
Let's look at how a request (high level) happens in an MVC application.
Request
Request hits the server with a url ex. /hello/world
That url is used to match any entries in your route table
When a match is found, that route defines basic values like what controller and action should be called.
The controller is created, and that action is called with the route values and other request properties (querystring, session, etc...).
Response
We are now in the controller action, run the code you need to fulfill the request
Pass the data to the View
The view is determined by convention and your ViewEngine
The view is then rendered and written to the response.
The request/response is finished.
Note
This whole process is determined by the route, and the relationship between the controller and view are trivial. Where the form is posted to is determined by you in the view by using helper methods that determine what route to hit in the next request/response flow.
Some Helper Methods.
#Url.Action("index", "home");
#Html.ActionLink("index", "home")
#using (Html.BeginForm("create", "home")) { }
To sum it all up, the relationship between the controller action and view is really facilitate by your routes. Once you have a grasp of how to create them, then you will better understand how to manage the interaction of your application. Hope that helps. :)
There is no such thing as "Postback" in MVC. In contrast to WebForms, a view only renders HTML to be sent to the browser. As soon as any type of request is issued by the browser, it goes to the controller, not to the view.
As for the relationships:
If you define a TestAController (note: Not "ControllerTestA"), it serves the "/TestA/*" URL's. If you have a method TestA in there it will serve "/TestA/TestA".
If your method returns View(someModel) it will look for a view named TestA.cshtml/TestA.aspx, named like your method, within a folder Views\TestA (named like your controller, without the "Controller" suffix)
The view will render the HTML based on the someModel passed by the controller.
Within the view you may call other URL's or post data to some. This closes the circle.
As for the parameters or overloads, there are some restrictions:
You can define overloads for GET vs. POST vs. PUT vs. DELETE. You will need to annotate the methods with the according attributes though.
However you cannot define multiple overloads of the same method name for POSTs with different sets of parameters. You will need to make your POST method signature such that parameters can or cannot be sent to the server:
Example:
public ActionResult TestA(
string someOptionalParameter, int? someOtherOptionalParam)
{
if (string.IsNullOrEmpty(someOptionalParameter)) { ... }
if (someOtherOptionalParam == null) { ... }
}
The model-mapper will set your parameters to null if they are not posted to the server.
Like Khalid already mentioned - you should not mix up the concepts of MVC and WebForms. They are very different. MVC has no such thing as a "view state" which could be posted to the server. It has no WebForm-like lifecycle for the ASPX (or CSHTML) pages.
If you have a form in a view, then that form has a url to which it will post to. This URL is in the Html.BeginForm method in your view.
The form will then be posted to the appropriate controller methond in the approoriate controller
So if BeginForm starts like this:
using (Html.BeginForm("AddProduct", "Product"
Then the action method "AddProduct" in the controller Product (ProductController is the class name) will be called.

ASP.NET MVC - How to Create a RESTful Controller Scheme?

If this is a duplicate, please let me know - because i had a quick look and couldn't find anything that really answers my question.
I'm experimenting with ASP.NET MVC 2. Now coming from a Web Forms background, i only really dealt with HTTP GET and HTTP POST.
I'm trying to see how i could apply GET/PUT/POST/DELETE to the respective CRUD operations on my repository (Find, Insert, Update, Remove).
Say i have a single controller, with the following action methods:
[HttpGet] // GET: /Products/{id}
[ActionName("Products")
public ActionResult Get(int id = 0) { ... }
[HttpPut] // PUT: /Products
[ActionName("Products")
public ActionResult Put(Product product) { ... }
[HttpPost] // POST: /Products/{product}
[ActionName("Products")
public ActionResult Post(Product product) { ... }
[HttpDelete] // DELETE: /Products/{product}
[ActionName("Products")
public ActionResult Delete(Product product) { .. }
Couple of questions on that - is that how you would name/separate the action methods? Should i be passing through the entire model (Product), or just the id?
The problem i'm having is i'm not sure how to handle invoking these action methods with the relevant HTTP Verb in my View.
At this stage, I'm thinking i would have 3 Views:
"Index" - bind to IEnumerable<Product> model, listing all products, with "Edit", "Details" and "Delete" links
"Single" - bind to single Product model, listing all details for a product, with an "Update" button.
"New" - bind to single Product model, with form for creating product, with an "Create" button.
So - my question is, how do i specify i want to invoke a particular controller method with a specific HTTP Verb?
With Html.BeginForm, you can specify a FormMethod enumeration - but it only has GET and POST.
How can i perform a PUT and DELETE command?
Will i need a seperate View for each HTTP Verb?
If i have a link called "Delete", can i invoke a HTTP DELETE command to my controller, or does it need to be redirected to a new View with the form action delete?
Or, is this a silly/overkill design in the first place, should i just stick with "GET" and "POST"?
I'm (fairly) new to this style of web development (REST), so please be kind. :)
UPDATE
So i came across this interesting article from Stephen Walther, regarding this very topic.
He indicates a HTML Form only supports GET and POST (because i'm new to REST-style web development, i did not even know this, to which i am partially ashamed).
Apparently the only way to invoke a Controller action with PUT/DELETE is to do it with AJAX. Seriously?
So what should i do here, should i stick with GET/POST, or should i create a JavaScript file which wraps the underlying XmlHttpRequest code behind a nice function?
Which way are ASP.NET MVC developers leaning? Surely someone has asked themselves this same question.
The reason that you're mostly familiar with GET and POST is because a regular old browser can only GET or POST a URL, especially when submitting a form.
Setting up your controllers this way, you're looking at something more along the lines of a REST API vs. a web site at least in spirit.
And yes, you are correct that only AJAX requests can set their request methods explicitly, so you're good to go if you'll be performing actions like deleting products via AJAX (in which case I would suggest only passing the ID since it is much lighter than serializing the entire product and you'll likely have easy access to the ID in your markup).
Here's the thing. If you are building a modern web application you're probably using AJAX and without getting too dogmatic you should expect your users to have JavaScript. If you want to do CRUD without AJAX then you can always POST a Product or use GET for a delete method with the ID in the URL (caveat to that, make sure the Delete method is protected behind authorization or a web crawler will gladly consume your GETs and delete all your data...)
If you don't want to build a REST API then don't sweat the fact that you're not using DELETE (just use GET with the ID in the URL) or you're not using PUT (just use POST with the product entity in the POST body).
REST is a great style for building APIs (no presentation tier, data sent in raw format to clients who consume them, could be a phone or a website, etc.) over HTTP. HTTP is great on its own for building web pages. Use what you need for what you need it for.
If you want to build a REST API to be used by both other people AND your web site, then do that, and just have your site's controller action methods call your API methods directly. I do that all the time. Use a web client like Hammock to make it easier on you.
Personally I stick to as simple as possible full requests, instead of going AJAX all over. I use ajax, but in specific places where it enhances the experience (and I do with a progressive javascript approach).
Because of the above, I always just use GET and POST.
As for the naming, for those I'd do: Get, Update, Create, Delete, which makes it pretty clear. I actually use more like an action name that's related to what the operation does, but for simple things those work fine.
HtmlHelper.HttpMethodOverride Method (System.Web.Mvc)
How about this?

Most Correct way to redirect page with Model-View-Presenter Pattern

What is the best way to call a Response.Redirect in the Model-View-Presenter pattern while adhering to correct tier separation?
One way I handled this is for the presenter to raise an event (like Succeeded or something) that the view would subscribe to. When the presenter finished it's processing, it would raise the event, which would get handled by the View. In that handler, the view would redirect to the next page.
This way, the presenter doesn't need to know anything about pages or URLs or anything. It just knows when it has completed its task and lets the view know by raising an event. You can raise different events if the presenter succeeded or failed, in case you need to redirect to different places.
I do not know whether it is the most correct way, conceptually.
But what I did in my last MVP-applications, is create a wrapper around HttpContext.Current which I called HttpRedirector.
I also created a dummy redirector for testing purposes. Both keep track of the last redirected url, so that I can check in my unit tests that the redirect actually happened when I call a method on my controller/presenter. With an IOC-container I am able to switch the implementation of IRedirector based on the environment (production/test).
The way we do it works nicely once some ground work is laid. I'm sure there are several ways to skin a cat though. (Who skins cats anyway. Cats are cute and cuddly!)
First, this will only work on the ASP.Net compiled Web Projects, not Websites.
Each page should inherit from a custom abstract base class which looks something like this:
public abstract class PageBase : Page
{
private static string _baseUrl = "/";
public static string BaseUrl
{
get { return _baseUrl; }
set { _baseUrl = value; }
}
protected static string BuildUrl(string basePath)
{
if( !string.IsNullOrEmpty(basePath) && basePath.StartsWith("~/"))
{
basePath = basePath.replace("~/", BaseUrl);
}
return basePath;
}
protected static string LoadView(string path)
{
Response.Redirect(path);
}
}
Each page also implements a page-specific interface. Each page-specific interface also inherits from a base interface:
public interface IPageBase()
{
void LoadView(string path);
}
Then it's a matter of each page defining it's own version of BaseUrl. You might want to account for querystrings/path encryption/etc.
Finally, any of your presenters (which should be referencing the page-specific interfaces) can grab the static BuildUrl() on a desired page to view and then call LoadView() with the returned path.
It depends how generic your presenters are. If your presenters are totally UI agnostic (can be reused between WinForms and WebForms) then you'll have to abstract the redirection operation. In WebForms, the redirection operation would be implemented in the view by a Response.Redirect. In WinForms, (I disclaim lots of experience with WinForms) my guess is that it would be implemented by SomeForm.Show.
One simple, off-the-top-of-my-head option would be to include in the view's interface a ShowViewX() method. You can have one for each form the view could logically redirect to. Alternatively, the view can implement an interface method like Show(ConnectedViews) where ConnectedViews is an enum that includes a value for each of the views that can be "redirected" to from a particular view. This enum would live at the presenter level.
The above approaches are specific to view-presenter pairs. You could instead implement it as a system-wide thing. The logic would be similar to above, implemented in the base view and presenter. There would be a ShowView__() for each form, or a Show(Views) method where Views is an enum of all forms.
It's a toss-up between encapsulation and DRY-ness.

Resources