I am trying after the btnCreate_OnClick event to reset the form to it's default value just like the first page_load. The problem is after PostBack, every textbox and other controls, reloads the ViewState value. I cannot deactivate viewstate because of server event on DropDownList selection. The only way I found so far is to Redirect to self after the click event, but this loads the page twice and is therefor a bad solution. I have try ViewState.Clear() and update the UpdatePanel, but was unsuccessful.
I could do a loop for all controls and set the txtXXXXX.Text == "", but I'm quite sure it's not the best idea.
Something like Page.Reset() would have been just perfect but it doesn't exist.
Any thought on this problem of mine?
Thanks
If workable, I usually just use Response.Redirect to reload the same page from scratch.
An initial GET request to a page usually costs less than subsequent POSTs anyway, so there's not much reason to avoid it.
We can reset the ASP.NET Form Page with just 2 lines of code
protected void Button_Reset_Click(object sender, EventArgs e)
{
Session["ViewState"] = null;
Response.Redirect("/Roster/DRAC/Create.aspx");
}
Self redirecting gets tricky because of viewstate.
There is an html input type "reset" for buttons, but I'm not sure what or any integration msft has put into viewstate/asp.net for this. It generally works for simple javascript forms.
ex:
<input type="button" value="Reset" onclick="document.<formId>.reset();">
from google ----^
One way, not necessarily ideal, is to reset the values to their defaults using Javascript. If it is a large form, it can be ugly, but will prevent the need to do a self-redirection.
You also might try Server.Transfer instead of Response.Redirect(/self/)
I dont know if this helps but i change the name of every input on the form that i want to get fresh values by using javascript before submiting the form, since the .net page can no longer match the values from the form to the controls for the page it reloads them as if there was no postback. i also append a new value to the form so i know what button submitted the form and use that logic to decide what to load into all the controls and how to process the form data of course.
$("#Bset").children().click(function() { //all the btns click function
$.each($("form").find("input"), function(e,v) { //could filter this to subset of inputs
$(v).attr("name", "_" + $(v).attr("name")); // ctrl1 becomes _cntrl1
});
$("form").append("<input type='hidden' id='b' name='b' value='" + $(this).text() + "' />").submit();
});
then in the code behind
protected void Page_Init(object sender, EventArgs e)
{
id = int.Parse(Request.QueryString["id"]);
bk = db.dc.getDetailBK(id).Single();
if (Request.Form.Count > 0)
doPostBack();
mrl = (from a in db.dc.getMetricQTD(id, null, null, loadSavedGoals) select a).ToList();
}
i can then do things in dopostback that process the form data, interact with the db etc. that may change the values mrl is loaded with and refresh the data in the inputs tied to mrl regardless of wether they were modified or not on the form.
the other alternative would be to tie some buttons to use a webservice to handle your db interaction then call window.location to refresh the page.
$.ajax({
url: "webservice/dbfunction?"
data: {which btn pressed, some form values etc...}
success: function() {window.location("samepage.aspx?id=xxx");}
...
});
this would also avoid having to response redirect on the server side.
In our case the best performance solution was to set manually for each control the default value in the click event ex:
textbox1.Text = null;
textbox2.Text = null;
This avoid the double page_load and the loop. We don't event have to update the UpdatePanel since it executes before render.
Maybe in a more complex web application we would have to Redirect as most people seem to accept this as a solution.
Setting per control the default value was better suited to our case.
Thank you
Related
I'm doing some URL changing to add some id values onto the end when certain components are clicked by the user.
So for example, when I'm logged into my AdminCP I have a list of user accounts which can have various things done to them, like modify the information or delete the user accounts.
The ASP.NET page i'm using is designed off a Master Page. That Master Page is also part of the Global Master page. So, like a nested master page.
When the user account is clicked, I record the Username in a Session Variable and then call that on page load with a button postback url. For example;
protected void Page_Load(object sender, EventArgs e)
{
if (Session["QueryString"] != null)
{
AdminHiddenButtonDelete.PostBackUrl = Request.Url.AbsolutePath + Session["QueryString"].ToString();
}
}
I'm setting the Session["QueryString"] when a button event is fired.
private void DeleteUser(string user)
{
admin_user_accounts_wrapper.Style.Add("display", "none");
admin_user_accounts_user_delete.Style.Add("display", "block");
Session["ClickedUserAccount"] = user; // This session is used to hold the username of the clicked useraccount
Session["QueryString"] = "?User = " + user + " ";
admin_user_account_user_delete_heading.InnerText = "Are you sure you wish to delete the user account " + user + "?";
}
This is called when the user clicks the html <button /> on the website.
Where query string houses the user accounts name. The outputted URL should then be url.aspx?User=John for example. Except, it always seems to be one postback behind. So, if I navigate to the John user, and then to the Rick user, the Rick URL will state John, and when I go back to the John user the URL will show Rick.
I hope this makes sense! I'm just not entirely sure on the best way to accomplish this.
To anyone who may of done something similar to me I want to post my answer on how I fixed this in hopes it may help other people out there.
The first thing I did was go back to some sort of basics about dynamic content, and realised I should be using an AJAX Update Panel to decrease the amount of postbacks that was happening.
The next thing I did was go through all my code line by line. I programmatically made a content container that houses for div id's and also some HTML buttons. These HTML buttons when clicked fired a JavaScript function. This function then called two hidden <asp buttons. That is where my mistake started.
The JavaScript function called a click event;
var hiddenButton = $('#<%= AdminHiddenButtonDelete.ClientID %>');
if (hiddenButton != null) {
hiddenButton.click();
This was my first mistake. I had now gotten two buttons, with one button doing a click server command twice, two post backs.
So, after removing the two hidden buttons and all the javascript I then needed to change the way I coded the content.
I swapped to using WebControls.Button and putting the contentResolver in the aspx.cs rather then its own class, then on click using new EventHandler(this.UserDelete_Click);
This tied the eventClick to my own function, allowing me to register the onClick event without postpacking as I'm using update panels.
(ASP.NET)
How do i prevent duplicate records insertion in my database when user refreshs the page after post back. i know it can handle by redirecting the page. it and also handle through the check if same entry exists inside the stored procedure. but this wont full fill requirement sometime. i just want to know is there any other good practice instead redirecting the page.
(I know it can also handle using AJAX, but i am not using AJAX)
Try this
if (!IsPostBack)
{
do something
}
You can use the Page.IsPostBack property
private void Page_Load()
{
if (!IsPostBack)
{
//logic
}
}
In the code example above, if the page is a postback then no code would be executed (the logic).
Ok, let me start this with I am more of an MVC person. I have a result set that I am trying to add paging. All I really want is a previous and next button on my page which are Link controls. I need these controls to post back to the same page, but have a query parm like page=4. How do I add these links? I see the PostBackUrl property on the link. Should I just use Request.Url and stuff it into PostBackUrl? Then I have to do string searches on the parm... it gets nasty. Is that the only way? I have tried ViewState, please dont suggest that... it is unpredictable garbage as far as I am concerned.
The PostBackUrl property is for cross-page postbacks, you don't want to do that.
If you want to use a POST, you can use a LinkButton, handle the click event, and rebind your result set. Something like
public void BackButton_Click(object sender, EventArgs e)
{
// Get existing page from session, viewstate, etc
// RebindGrid
}
If you want to use a GET, you can use a HyperLink and set the NavigateUrl property to the correct Url. Something like
int page;
if( !int.TryParse(Request.QueryString["page"], out page) )
page = 1;
if( page > 1 )
BackUrl.NavigateUrl = Request.Path + "?page=" + (page-1).ToString();
else
NextUrl.NavigateUrl = Request.path + "?page=" + (page+1).ToString();
// Note: not syntax/bounds checked
Edit:
Perhaps what you're looking for a Post-Redirect-Get pattern?
Response.Redirect(HttpContext.Current.Request.Path + query, true);
You're talking about ASP.NET Webforms or MVC?
If you're talking about Webforms I don't think that you'll have success on that. I believe that you'll need to control this move between your pagination with Session or other way or re-bind your data for each page.
What I ended up doing was putting hiddens on the page for the vars I needed to pass back, then I read those. This is things like page number, which allows me to calculate prev and next page. Sorry to submit my own answer but this was a little odd and I thought I would tell what I ended up doing.
View state for some reason was empty every time, so it was doing me no good. This is in a DNN app, and I didnt want to spend time figuring out why viewstate was messed up.
I have an ASP.NET2.0 web page with a Submit button.
When the user clicks, I generate an XML file on the fly and return that as a result.
Here is the code:
protected void submitBtn_Click(object sender, EventArgs e)
{
string result = this.ProduceMyXmlResult();
this.Response.Clear();
this.Response.StatusCode = 200;
this.Response.ContentType = "application/xml";
this.Response.ContentEncoding = System.Text.Encoding.UTF8;
this.Response.Write(result);
this.Response.End();
}
The piece of code does exactly what I want. However, the browser does not recognize the XML file as a new page, so the BACK button does not take me back to my original page. Why and how can I overcome that?
The simplest way to do so, I think, would be to create a separate page that executes this code on Page_Load(), and redirect to it when the button is pressed.
The reason you have no backward navigation is because the browser is unaware the page has changed. Since the Submit button is preforming a postback, and you are returning XML data as the response to that postback, it appears to the browser as though this is just some transformation of the current page (just as though you'd, say, changed the text of a Label control).
The "correct" way to accomplish this would be with some type of HTTP handler, but I haven't the experience to suggest the proper way to do so and you already have working C# code-behind for this method.
I have a search form in an app I'm currently developing, and I would like for it to be the equivalent of method="GET".
Thus, when clicking the search button, the user goes to search.aspx?q=the+query+he+entered
The reason I want this is simply bookmarkable URLs, plus it feels cleaner to do it this way.
I also don't want the viewstate hidden field value appended to the URL either.
The best I could come up with for this is:
Capture the server-side click event of the button and Response.Redirect.
Attach a Javascript onclick handler to the button that fires a window.location.replace.
Both feel quirky and sub-optimal...
Can you think of a better approach?
Use a plain old html form, not a server side form (runat=server), and you should indeed be able to make it work.
This could however be a problem if you have an out of the box visual studio master page which wraps the entire page in a server side form, because you can't nest forms.
Web forms don't have to suck, but the default implementations often do. You don't have to use web forms for everything. Sometimes plain old post/get and process request code will do just fine.
I worked on a web site that had to post to a 3rd party site to do the search on the client's web site. I ended up doing a simple Response.Redirect and passed in the search parameters through the query string like so:
protected void Button1_Click(object sender, EventArgs e)
{
string SearchQueryStringParameters = #"?SearchParameters=";
string SearchURL = "Search.aspx" + SearchQueryStringParameters;
Response.Redirect(SearchURL);
}
And on your Search.aspx page in your pageload...
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(Request.QueryString["SearchParameters"]))
{
// prefill your search textbox
this.txtSearch.Text = Request.QueryString["SearchParameters"];
// run your code that does a search and fill your repeater/datagrid/whatever here
}
else
{
// do nothing but show the search page
}
}
Hope this helps.
This function permits to submit a page using the GET method.
To submit a page using the get method you need to:
add this code Form.Method="get"; in the Page_Load method
Use this code < asp:Button runat="server" ID="btnGenerate" /> as a submit button
add rel="do-not-submit" attribute to all form elements that you don't want to include in your query string
change the codebehind logic of your page using Request.QueryString
disable the page viewstate with EnableViewState="false" (unless it's used for other purposes)
Code
$(document).ready(function(){ enableSubmitFormByGet(); });
function enableSubmitFormByGet(){
if($("form").attr("method") == "get"){
$("form").submit(function() {
$("[name^=" + "ctl00" + "]").each(function(i){
var myName = $(this).attr("name");
var newName = "p" + (i-1);
$(this).attr("name", newName);
});
var qs =$(this).find("input[rel!='do-not-submit'],textarea[rel!='do-not-submit'],select[rel!='do-not-submit'],hidden[rel!='do-not-submit']").not("#__VIEWSTATE,#__EVENTVALIDATION,#__EVENTTARGET,#__EVENTARGUMENT").serialize();
window.document.location.href = "?" + qs;
return false;
});
I would do (b) since (a) would require two round trips for a single query. Alternatively, you could disable viewstate on the page, remove any other hidden fields via javascript, and also use javascript to modify the form method from post to get. I've never done this for real, but my toy page using the included sample worked like a charm. It's arguably easier than encoding the search string and doing the get via javascript.
Actually, it sounds like you would be happier with ASP.NET MVC since this is easily doable there by simply setting the form method to GET in the view.
sample code using jquery
$(document).ready( function() {
$('input[type=hidden]').remove();
$('form').attr('method','get');
});
EDIT: It seems like you ought to be able to do the same thing server-side, too. Maybe in OnPreRenderComplete. Don't have access to Visual Studio right now to check.
I have always used Response.Redirect as it "works".
I don't think there is an optimal method.
Just use this in your .click event before the form submission:
$("#__VIEWSTATE").remove();
$("#__EVENTVALIDATION").remove();