How does Asp.net Knows which Page to Generate? - asp.net

When a client is on page A.aspx , and he press some button there is a postback.
The server knows which page to rebuild according to the request.
but how does the client knows which page to re-ask ? by the current url of his browser ?
where this information is saved in the client side ?

Its defined in the action property of <form>. The client does not need to re-ask, the server sends a response of his request.

ASP.NET is just a part of the .NET framework, but what every client sees on a web browser in plain old HTML.
ASP.NET gives you several controls that makes it easy to use them programatically, so we can set all sort of things in our code (that is run before the page is showing) to do the exactly what we want.
every link, button, image, grid, it's just HTML tags, like <a> for links, <input type="button"> for buttons etc...
Keep in mind that now, there are 2 variantes of the ASP.NET, the WebForms and the MVC (you can also read about choosing one in prole of the other)
in every ASP.NET WebForms there is always a <form> on the start of the <body> and wrapps all your code, so, any submit will do a PostBack into the same file name, in your example A.apsx will always post into A.aspx, then if you want, for example, send that request to B.aspx you need to have a Click Event that would use the Server.Transfer("B.aspx") and that would redirect the entire post to B.aspx just like it was a post from B.aspx
in the newest pattern, the ASP.NET MVC, it drives with Routes witch let's you set up any, every, one, multiple, ways to reach the same page. In MVC the URL does not point to a specific page, but to a specific Controller and it's up to the Controller to send, after processing the data, to a specific View, that is why in MVC there are no pages in the url (though you can add it to the route if you want, and you can accomplish the same with WebForms using a Routing plugin).
Now, in MVC it's there is no <form> wrapping up your entire code, you need to, if you want to submit something, create your own <form> and point to the correct route
but, just like in Webforms or any HTML page, posts are made through form submittion, and it's "path" it's always whats in the form attribute action that let's you know what's the next step.
I hope this helps you realizing that there is no big monster in ASP.NET, that is only a way to reuse controls and access them programmatically and that, in the end, it's all HTML :)

A general answer: on the client side it's either a submit from within a form or a link.
The form points to either a relative URL (that means the current URL plays a key role) or an absolute URL (the current URL plays little to no role).
For links it's generally the same: either they are relative or absolute. One big difference: links are use HTTP GET while forms can use HTTP POST (thus transferring more data without encoding them to the URL as parameters).
For a button it's the form that gets submitted.

Related

JSF page forward - slow CSS [duplicate]

I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
It seems like JSF has been around for long enough that there must be a clean, solid way to deal with this. If so, would you mind sharing?
I have found various workarounds, but sadly nothing that seems like a real solid solution.
Simply accept that the URL is misleading.
Append "?faces-redirect=true" to the return value of every bean's action and then
figure out how to replace #RequestScoped with something else (Flash Scopes, CDI conversation, #SessionScoped, ...).
accept to have two HTTP round trips for every user action.
Use some method (e.g. 3rd party library or custom code) to hide the page name in the URL, always using the same generic URL for every page.
If "?faces-redirect=true" is as good as it gets, is there a way do configure an entire application to treat all requests this way?
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the <h:form> is been requested form. You can confirm it by looking at the <form action> URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use <a>, <form>, <h:link> or <h:button> instead of <h:form> and <h:commandXxx>).
For example, page-to-page navigation, Google-like search form, etc.
If the request is non-idempotent, just show results conditionally in the same view (i.e. return null or void from action method and make use of e.g. <h:message(s)> and/or rendered).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.
If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with ?faces-redirect=true from action method, or manually invoke ExternalContext#redirect(), or put <redirect/> in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
See also:
What is the difference between redirect and navigation/forward and when to use what?
JSF implicit vs. explicit navigation
What URL to use to link / navigate to other JSF pages
Bookmarkability via View Parameters feature
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
When should I use h:outputLink instead of h:commandLink?
Creating master-detail pages for entities, how to link them and which bean scope to choose
Retaining GET request query string parameters on JSF form submit
Pass an object between #ViewScoped beans without using GET params

Possible to only update part of page and change query string parameters at same time in asp.net?

Is there a way to only update part of the page and update the query string parameters at the same time without completely refreshing the whole page in ASP.NET?
I only need to update the "main" section of my page and not the whole page. I understand I can do a partial page postback (or use asp ajax) to do the partial page update, but then how do I update the query string parameters in the URL at the same time? Is that even possible?
Or is it not possible and I'll have to just do a Response.Redirect in the code behind of the partial page postback redirecting to the same page with new query params and just let the whole page refresh?
Use pushState.
This new feature offers you a way to change the URL displayed in the browser* through javascript without reloading the page. It will also create a back-button event and you even have a state object you can interact with.
window.history.pushState(“object or string”, “Title”, “/new-url”);
Described here
You have absolutely zero programmatic access to the address bar. The only way to change it is to redirect.
You could, however, do it like some sites do and provide a "send a link to this page to your friends" area. Youtube comes to mind - see how it provides a URL, querystring parameters included, for you to copy, should you wish to send someone a link to a video starting from some specific point.
Also check the handy "Share" link right under your question. You could provide a link like that, with the target URL, so for the user it's just a matter of right-clicking and copying from the context menu. A link well structured into your site is more user friendly than having the user copy directly from the bar, or from a text box. Specially for mobile browsers, where the sequence is usually press-and-hold, then copy. Copying from the address bar, on the other hand, may involve selecting the address bar text, which in some Android devices is a pain in the ass.

aspx ashx mash-up

I'm retro-fitting a .aspx page with AJAX functionality (using VB, not C#). The codebehind populates the page with data pulled from a web-service. The page has two panels that are populted (with different data, of course) in this way. On a full page refresh, one or both panels might need to be populated. But populating Panel 2 can take a long time, and I need to be able to update panel 1 without refreshing Panel 2. Hence the need for AJAX (right?)
The solution I've come up with still has the old .aspx page with .aspx.vb codebehind, but introduces a Generic Handler (.ashx) page into the mix. Those first two components do the work on the user's first visit or on a full page refresh, but when AJAX is invoked, the request is handled by the .ashx page.
First question: Is this sound architecture? I haven't found a situation online quite like mine. Originally, I wanted to make the .aspx page into the AJAX handler by having the codebehind implement IHttpRequest, and then providing "ProcessRequest" and "IsReusable" methods, but I found I couldn't separate a regular visit to the page from an AJAX request, so my AJAX handlers took over even on the first visit to the page. Second question: Am I right to think that this approach (making the .aspx page do double-duty as the AJAX handler) will never work? Is it impossible to tell whether we're getting a full-page request or a partial-page (AJAX) request?
If the architecture is good, then I need to dynamically generate a lot of HTML in the .ashx file, right? If that is right, should I send HTML back to the client, or should I encode it in some way? I've heard of JSON encryption, but haven't figured out how to use it yet. So, Third question: Is "context.Response.Write" the only pipeline for sending data back to the client? And, if so, should I send back HTML or some kind of JSON-encoded objects?
Thanks in advance.
It sounds as if the page requires some AJAX functionality added to the UI.
Suggest using an UpdatePanel for each web form element that needs to have AJAXy refresh
functionality. That'll save you from having to refactor a bunch of code, and introduce a whole lot of HTML creation on your .ashx.
It'll be more maintainable over the long run, and require a shorter development cycle.
As pointed out by others, UpdatePanel would be a easier way - but you need to use multiple update panels with UpdateMode property set as conditional. Then you can trigger the update-panel refresh using any button on the page (see AsyncPostBackTrigger) or even using java-script (see this & this). On the server side, you may decide what has triggered the partial post-back and act accordingly by bypassing certain code if not needed.
You can also go with your approach - trick here is to capture the page output using HttpServerUtility.Execute in your ashx and write it back into the response (see this article where this trick has been used to capture user control output). Only limitation with this approach is that you can only simulate GET requests to your page and so you may have to change your page to accept parameters via query string. Personally, I will suggest that you create a user control that accept parameters via method/properties and will generate necessary output and then use the control on your page and in ashx (by dynmaically loading it in a temperory page - see this article).
EDIT: I am using jquery to illustrate how to do it from grid-row-view.
$(document).ready(function() {
$("tr.ajax-grid-row").click(function() {
$("#hidden-field-id").val($(this).find(".row-id").val()); // fill hidden filed
$("#hidden-button-id").click(); // simulate button click
});
});
You can place above script in the head element in markup - it is assuming that you have decorated each grid-row-view with css class "ajax-grid-row" and each row will have hidden field decorated with css class "row-id" to store row identifier or the value that you want to pass to server for that row. You can also use cell (but then you need to use innerHTML to get the value per row). "hidden-field-id" and "hidden-button-id" are client ids for hidden field and submit button - you should use Control.ClientID to get actual control ids if those are server controls.
JSON is not for that purpose, it is to pass objects serialized with a nice light weight notation, is you need to stream dinamically generated html using ashx, response.Write is what you have. You may want to take a look at MVC
Or you could use jquery if it's just html, the simpliest would be the load function, or you can look into Ajax with jquery. Since the ashx can be served as any resource it can be used in the load function.
I agree with #p.campbell and #R0MANARMY here. UpdatePanel could be the easiest approach here.
But then like me, if you don't want to go the UpdatePanel route, I don't see anything wrong with your approach. However, generating the html dynamically (entirely) at the back end is not a route I'll personally prefer (for the maintainence reasons). I'd rather prefer implementing a solution that will keep the design separate from the data.

MVC: capture route url's and pass them to javascript function

Short:Is there a way to have a route-definition that will pass the "CONTROLLER/ACTION" string value to a JavaScript function in stead of actually going straight for the controller action?
More:I have a masterpage which contains the navigation of the site. Now, all the pages need this navigation wrapped around it at all times, but because I didn't want the navigation to constantly load with each pagecall, I changed all my pages to partialviews.
These partial views are loaded via the JQuery.Load() method whenever a menu item is clicked in the navigation.
This all worked very good, up till now because I noticed it's also a requirement of the website to be able to link directly to page X, rather then default.aspx.
So, as an example:The main page is my "default.aspx" page, this utilizes my master page with the navigation around it. And each call to a new page uses a javascript function that loads that particular partial view inside a div that is known in my masterpage. So, the url never changes away from "default.aspx", but my content changes seemlesly.
The problem is, those url's also need to be available when typed directly into the address bar. But, they're partial views, so loading them directly from the address bar makes them display without any masterpages around them. Therefore my question if it might be possible to capture the route typed into the address bar and pass that on to my JavaScript function that will load that route in the content div.
(I hope I explained it ok enough, if not, feel free to ask more information)
You are 100% correct to not want to hard code your URLs in your javascript code as it demolishes one of the primary tenants of MVC to do so. I'm one of those "separation of concerns" guys who will not write a single line of javascript outside of a dedicated .js file so I cannot dynamically specify the URL the way tuanvt has. What I do is use MVCs Url.Action method to emit my service URLs into hidden inputs on the master page (or the specific page if it is not used in multiple places). Then my script file simply pulls the value out of that hidden input and uses it just fine.
ASP.NET MVC View Source
<input id="serviceUrl" type="hidden" value="<%= Url.Action("Action", "Controller") %>" />
JS Source
$.getJSON($("#serviceUrl").val(), function(data) {
//write your JS success code here to parse the data
});
First challenge, as you are using AJAX to load the partial pages you need client accessible URLs for the javascript to call. Second challenge, you need URLs that will load the HomeController and pass the 'page' portion of the URL into the javascript.
For the first aspect I'd create some abstracted routes, i.e. "/ajaxaccess/{controller}/{action}/{id}" for the partial pages. That would be the first registered route. A second route would accept any controller/action reference and always get processed by the HomeController Index action.
In the /Home/Index action you grab the requested URL and slice it up, take the /{controller}/{action}/... section and pass that into your default.aspx using TempData. In your page check for the existence of the TempData and if it exists use the value therein to trigger your AJAX page load for the partial page (don't forget that you'll need to prepend '/ajaxaccess' (or whatever you choose) to the URL before it's passed to your page.
I'm not going to provide code here as I think the information you'll gain from working through this yourself will be invaluable to you moving forward.
You could use hash anchor (#) on your url and read it with javascript.
var url = document.location.toString();
if (url.match('#')) {
anchor = url.split('#');
// do whatever with anchor[1] ..
}
You can do something like this, put this in your javascript code on the view:
var szUrl=<%= ViewContext.RouteData.Route.ToString()%>;
Then the current route will be stored on the variable szUrl.

Can I change the browser URL while maintaining ViewState in ASP.NET?

I'm doing some brainstorming for a portal framework, and I'm envisioning a breadcrumb navigation stack that is tracked via the ViewState (so that if the user clicks "back" in their browser and clicks some other link, the breadcrumb trail will depart from the right page). My pages are really just ascx controls that get loaded into a placeholder control on the main portal page based on the URL. When the user clicks a portal link, there is a postback that loads the original page and invokes the given link's "clicked" handler, which should then "push" the current location onto the breadcrumb stack before sending the browser a redirect instruction to change the URL to that of the page that I want to go to.
That's as far as my brainstorming goes for the moment, because once we perform a redirect, we lose the ViewState. Rather than doing the redirect, I've thought of simply telling my main portal page to replace the current page control with the target page control, thus avoiding the extra http round-trip and allowing me to keep the ViewState. But then my entire website experience occurs in the context of a single URL, so I lose URL bookmarking among other things. And if I wrap some of my controls in AJAX panels, the entire site happens in one page request as far as the browser's history is concerned.
What I would like is some way to have the browsing history and URLs behave as if each link is leading them to a new page with a descriptive URL and all that, but still have some way to know the path that the user took to get to the page that they're on (ViewState seeming to be the simplest way to track this).
Could anyone suggest some techniques I might try using?
First suggestion... You may want to look into ASP.NET MVC. However, I have to admit to some ignorance here as I'm not sure that would really solve your problem. But it sounds like the sort of thing MVC would be suited for.
Second... it's possible to override the methods responsible for saving and loading ViewState. One of the things you can do, for instance, is push the ViewState into the Session rather than sending it down to the user and back up on postback. You could easily add some custom code here.
Third... I think you may want to rethink part of your design. The ViewState really serves one purpose: It recreates the state of the page as it existed when the page was rendered for the user. If you are moving to a different page, or a new set of controls, why would you need the ViewState at all? The ViewState itself is really just a hack to begin with... ASP.NET's way of maintaining state on top of a stateless system. (but that's a whole 'nother discussion) We have other methods of maintaining state... the primary mechanism being the Session object. Why not save your breaacrumb data there instead?
I would look at using cookies. For performance reasons, you really want to avoid HTTP redirects if you can, and ViewState only works if the user submits a form, not for regular links.
You might do something like maintain several path lists in cookies that show the path that the user took to go from one page to another. Maybe you set a unique ID with each page that is applied by some JavaScript as a query string when the user clicks on a link, and the server uses that ID and the past history from the cookies to determine how to render the bread crumb on the next page?

Resources