Calling a ASP Page thru it Class - asp.net

Like in Windows Forms:
Dim myForm as New AForm(Constr-arg1, Constr-arg2)
myForm.Show
... is there a similar way to Load a Page in ASP.Net. I would like to overload the Page Constructor and instantiate the correct Page Contructor depending on the situation.

Can you just link to the page passing parameters in the QueryString (after the ? in the URL) and then use them in the constructor (more likely PageLoad)

I think the best approach here for ASP.NET is to write User Control (*.ascx file) that represents page content, and load different controls based on current situation using Page.LoadControl() method. This solution is flexible enough, because only reference to control is its name. And this approach is much more useful than page constructor overloading as soos as you're not related on strong types, only on controls' names.

This isn't really the "correct" way to redirect to a page in .Net web programming.
Instead, you should call either Request.Redirect("~/newpage.aspx") or Server.Transfer("~/newpage.aspx"). You should then handle the request in the new page's Page_Load handler.
You can pass state between the pages by adding to the query string of the redirected URL (i.e. ~/newpage.aspx?q1=test), or by assiging values to the Session store (i.e Session["q1"] = value).

Related

How can I do a partial page update with ajax using Sitecore?

I have a specific page (sitecore content item) in my web application composed of a sitecore layout and many sublayouts. One of those sublayouts is a user control that I would like to have refreshed once a certain button is clicked. I would like only that sublayout to be refreshed and the rest of the page to remain unchanged (typical ajax situation here). How do I accomplish this with sitecore when all of my sitecore content items are directly related to a full page in my web application (layout with sublayouts)? In my case, I want to use ajax to return the content of a specific, single sublayout only. What is the best practice for this kind of ajax situation with sitecore? I'm using sitecore 6.5.
Since you use the phrase "partial page update", I assume you are using an UpdatePanel. This doesn't really function any different than it would in a traditional ASP.NET application. You will handle the button click in a server-side handler method, modify properties on controls and let the update panel handle the rest.
If you are not using update panel, you have a few options depending on exactly what you want to achieve.
Typically, if you are clicking a button to trigger an ajax request, you are posting some data back to the server. For this case you would usually set up a web service to process the data and return some result. Your service can access Sitecore data, but does not utilize the Sitecore presentation engine.
Another option would be to make the request to a Sitecore page (possibly the same as the original request), but include a querystring parameter to trigger a different device. You could configure this device to render JSON, XML or a fragment of HTML rather than the normal Layout and battery of sublayouts.
Another option would be to use the Sitecore Item Web API. If you go this route, you will have another array of options (and a bit of a learning curve as well). Start by reading the documentation on SDN or some of the many blog posts on the topic.
There are a number of options available for achieving asynchronous behavior. None of these really relate to Sitecore directly, however, there are some Sitecore specific things to watch out for which I have highlighted below.
UpdatePanel Control
If you are performing something trivial where ultra-fast performance isn't a concern, simply wrap your button (and any other .NET controls that you would
like updated) in an UpdatePanel Control. You will also need to drop
a ScriptManager control into your base layout near the top inside
the <form> element. NOTE: When using this method, you will need to ensure that that your Sublayout does NOT have caching enabled, otherwise your button will not postback properly
Create your own web service
In this scenario, there are many client-side frameworks available for achieving the same result. My preferred method is to hook onto the client-side button click event with jQuery, prepare a request object, and post it to the server (getting back the information you need to update the client).
Here are a number of web service options that work with Sitecore - allowing you to have access to the Sitecore.Context and all of the subsequent Sitecore APIs.
Create an empty ASPX Web Form that accepts parameters as query strings. In the Page_Load method, do some work with the parameters and write directly to the response using Response.Write(). A JavaScriptSerializer comes in handy for serializing to JSON, just be sure to set Response.ContentType = "text/javascript";
Create an ASMX Web Service and decorate your methods with [WebMethod] (or [WebMethod(EnableSession = true)] if you need access to Session data).
Use MVC Controllers (ex: ASP.NET Web Api) to create an API. I believe there are some issues to work around in Sitecore 6.5 as described here.
Since this is all contained within a single Sublayout, you could simply use a standard <asp:UpdatePanel> surrounding your button and the usercontrol. In the code-behind, you can then do whatever databinding / data retrieval necessary to update the content of the usercontrol.
Note, if the button was on a different sublayout to the one where the content needs to be updated, you can use the approach described in this question as long as both controls have their content within <asp:UpdatePanel>.
In answer to your other question:
What is the best practice for this kind of ajax situation with sitecore?
There's not really a Sitecore-specific best practice for this sort of thing. In this case, any approach which works for plain ASP.NET will also work with Sitecore. The approach I described above is probably the simplest and quickest to implement, but you could also do this via jQuery and ajax to call a web service to load updated content.

ASP.NET dynamically adding UserControl and cache data on postbacks

I have a Report.aspx page that loads different UserControls to view specific object data alternatively. The UserControls inherit the same base type class where override the specific operations methods. I use a specific Service class for each UserControl to get data which implements a specific interface with operations signatures.
I now use a factory pattern to return the actual UserControl type to the Report.aspx and load it into a PanelControl, then call the control method to fetch some data based on some arguments.
This UserControl should be loaded in every postback due to the dynamic nature of it, any other solution is accepted. On every postback though I don't need to load data from the BL which calls the DL. I try to find a solution to show to the BL that I don't need you to call for the data again because I'm just posting back for other issues (e.g. download a report file, print etc.). And I would like this to happen on the BL level, not the ASPX front end. So far I think that I should let BL somehow know this (PostBack or !PostBack). I guess I could just create a parameter true, false and pass the PostBack property.
Any ideas, architecture and best practices are so welcome.
why not wrap the logic to call the BL inside the if(!Page.IsPostback){....} ?
Can you elaborate your statement "On every postback though I don't need to load data from the BL which calls the DL."?? During each postback, user control needs data to show (even if it is same data as last postback) because usercontrol goes through same lifecycle as ASPNET webpage. How can you prevent that?
I have decided that a very nice solution is System.Runtime.Caching in .NET 4.0.
Works very nice for every layer you need to use it.
http://msdn.microsoft.com/en-us/library/dd985642

Best way to generate url via Page.GetRouteUrl in a helper class?

I have just added routing in a new asp.net 4 web forms application, and have got my route table set up ok and page requests are working fine.
What I now want to do is use the Page.GetRouteUrl method whenever I need to generate one of my seo friendly Url's. I started to implement this across various pages then thought it might cut down on code a bit if I had a method in one of my own helper classes, that constructs this url (using the Page.GetRouteUrl method) as I might have several parameters that need to be specified against the Page.GetRouteUrl method each time.
However, within my helper class, it doesn't know what 'Page' is. I was thinking I could pass in 'Page' from the page that wants a routed url to be generated, but in some cases I want to construct one of these Url's in another class which doesn't know what 'Page' is, and in that scenario wouldn't be able to pass it in as a param (and therefore wouldn't be able to use the Page.GetRouteUrl within my helper class).
What is the normal approach when wanting to use Page.GetRouteUrl within classes that don't have an instance of the Page object?
You can pass Page as a constructor parameter, or this is actually the page reference:
var page = HttpContext.Current.Handler as Page;
You can cast it to the page type. Depending on the type of requests you are making, it may not always be page (say from a web service call, etc.).
HTH.

ASP.NET Page.User is null during AJAX request

I'm using the MVC2 framework and one of my views has a bit of conditional logic that gets the Page.User.Identity object and does a comparison with other values to determine what to display.
That all works fine on the initial page load, but when I make an AJAX call to get partial page updates (I'm doing this all manually with YUI3, not the .NET AJAX stuff) the Page.User object is always null.
Anyone know why the Page context seems to be discarding the User object for asynchronous requests?
Thanks,
Chris
If your request-handling method is a static WebMethod, there won't be a page instance to work with and Page itself will be null (that is, you won't even be able to resolve Page.User).
If that is indeed the problem, use HttpContext.Current.User instead. (And be sure to read Why do ASP.NET AJAX page methods have to be static?)

Using a Base Controller for obtaining Common ViewData

I am working on an ASP.NET MVC application that contains a header and menu on each page. The menu and header are dynamic. In other words, the menu items and header information are determined at runtime.
My initial thought is to build a base Controller from which all other controllers derive. In the base controller, I will obtain the menu and header data and insert the required information into the ViewData. Finally, I will use a ViewUserControl to display the header and menu through a master page template.
So, I'm trying to determine the best practice for building such functionality. Also, if this is the recommended approach, which method should I override (I'm guessing Execute) when obtaining the data for insertion into the ViewData.
I'm sure this is a common scenario, so any advice/best-practices would be appreciated! Thanks in advance!
EDIT:
I did find the following resources after posting this (of course), but any additional anecdotes would be awesome!
http://www.singingeels.com/Blogs/Nullable/2008/08/14/How_to_Handle_Side_Content_in_ASPNET_MVC.aspx
How do you use usercontrols in asp.net mvc that display an "island" of data?
Depends on where your information is coming from. We have standard view data that we use to generate some of the information we have on screen that we create in just this fashion. It works well and is easily maintained. We override the View method to implement strongly typed view names and use this information to retrieve some of the data that the master page requires as well.
You could write a helper extension to render the header/menu
That way you could have it show in different places in the view should you need to, but only one place for maintenance.
public static HtmlString MainMenu(this HtmlHelper helper)
Use a base controller class to implement generell filter methods. The controller class implements some filter interfaces IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter which are usefull to implement some common behavior for all controllers.
If the menu data is the same on all pages but different for each unique user.
Generate the menudata in an OnAuthorization or Initialize method of your controller base class. First will be called on authorization. Initialize will be called before every action method. You have access to ViewData Context. Generate the menudata there.
Put the view content for menu and header into the master page and access generated ViewData there.
I tackled a similar design challenge a couple months ago - implementing a breadcrumb feature that changes as user navigates from page to page.
I overrided the OnActionExecuting method to gather the breadcrumbs and store them in ViewData (I use the name of the action as the breadCrumb of the view). Then I updated the Master page to include a user control that takes the ViewData and renders the breadcrumbs.
One thing to be aware is that if you were using the default ASP.NET MVC error handling attribute [HandleError] and your error page is using the same Master page that attempts to read the ViewData, you will soon find out that you can't access ViewData from your error page and it will raise an exception. Depending on whether you need the ViewData for failure scenarios, the viable solution is to use a separate Master page or do this: How do I pass ViewData to a HandleError View?
I'll answer your question with another question. Will the base controller have to determine what type it really is in order to generate the proper menu data? If so, then you're defeating the purpose of polymorphism and the code to generate the data should go in each controller, perhaps in OnActionExecuting if the menu is the same for all actions. Pushing it back down into a parent class seems likely to end up with some switch statement in the parent class doing what each derived controller really ought to take care of.

Resources