calling alert from code-behind - asp.net

i have a dropdownlist and a listbox both asp.net controls
i am trying to prevent the user add duplciate items to listbox control
i able to block it but i want to display DIV or Alert box saying,"duplciate names are not allowed"
protected void btn_AddRecipientAction_OnClick(object sender, EventArgs e)
{
if (Convert.ToInt32(this.ddlRecipient.SelectedValue) > 0)
{
if (ddlRecipient.Text.Length > 0)
{
//var items = new System.Collections.ArrayList(this.lstRecipient.Items);
for(var i = lstRecipient.Items.Count - 1; i >= 0; --i)
{
if (lstRecipient.Items[i].Text == ddlRecipient.SelectedItem.Text)
{
lstRecipient.Items.RemoveAt(i);
**//alert("duplicate entry not allowed")
//div display the message and disappears after few seconds?**
}
}
ListItem newList = new ListItem();
newList.Text = ddlRecipient.SelectedItem.Text;
newList.Value = ddlRecipient.SelectedValue;
this.lstRecipient.Items.Add(newList);
}
}
}

alert way:
You could use this line assuming you have a ScriptManager
ScriptManager.RegisterClientScriptBlock(this,this.GetType(),"alert","alert('duplicate entry not allowed');",true);
This, however still does a postback since the script is run when the page is loaded again after the click. A better solution is to validate in client using javascript before submitting the page.

What you want is actually two separate things.
You should be validating on in the code behind, checking for duplicates on the post back. Then, use some javascript to do the same check on the client.
You MUST check for duplicates on the server since the user may not have javascript turned on.

Wow! Please don't inject js in the page to alert the user. You should instead have a notification control that receive a dataset of messages like an array then display the messages to the user. You want to separate your concerns.
You can achieve that in js. At the server you can set the array in json in a hidden field and then at the document ready event in js read that json data, parse it and loop on the array and display you messages. If you must you can use alert to display them but you should avoid it since it's so 1990's.
But I would go beyond that. I you do all the processing and validation in javascript before it gets to the server. So you don't rely on a post back to execute your validation. So as soon as the user adds the item it's told that it's a duplicate. Then, once the list is filled by the user he could save with a ajax call or post the page and at the server you parse the list, validate it and save it. If you have to compare the list to one already persisted at the server you can do that there. SOme thing goes wrong? you add the message to the notification control.
Please think about it. Try using a framework like MVC to separate you concerns. I makes the hole thing much faster to develop and so easier to maintain.

To call some JS from the code behind you can use Page.ClientScript property and call the RegisterStartupScript() method
http://msdn.microsoft.com/en-us/library/asz8zsxy.aspx

Related

ASP.NET conditional yes/no messagebox

I have an asp:Button that fires a code behind function on the OnClick event. In that OnClick event several things happen, and among those things I do a check in the database for if I need to ask the user a yes or no question. For that I need a message box. First I did it like this:
protected void MyButton_Onclick(object sender, EventArgs e)
{
// lots of stuff happening
bool iNeedToAskTheUser = INeedToAskTheUser(stuff);
if (iNeedToAskTheUser)
{
DialogResult result = MessageBox.Show("Do you want to fix all objects?", "Fix objects", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes) // do stuff
}
// some other stuff
}
This works fine locally but not when deployed, so I figure I would need to use ScriptManager.RegisterStartupScript instead. I could just add javascript on the ASPX page that fires up a dialog and saves the response in a hidden control that I can then look at, but I don't want to fire up the dialog unless I have to, which I check for before I do the DialogResult in the code above. So I can't do that immediately when the user clicks the button.
Is there any way I can use ScriptManager.RegisterStartupScript in "the middle" of my _OnClick code so that I can choose whether or not to actually show the button, and then also know if the user clicked yes or no, (preferably) without doing a postback?
I've been thinking and testing two different solutions:
Use ScriptManager.RegisterStartupScript in code behind to fire a JavaScript confirm function on the ASPX page. The JavaScript function would set a value in a hidden control depending on if the user answered yes or no and then my code behind stuff would check the value of that hidden field and act upon that. The problem with that is that once ScriptManager.RegisterStartupScript fires it doesn't wait for the JavaScript function to "finish", ie wait for the user to reply to the confirm(). So the value in the hidden control will always be empty because the code behind gets to the check of that control before the user has a chance to respond to the confirm(). So that's a no go.
Use ScriptManager.RegisterStartupScript in code behind to open up a new ASPX page that asks the user the question and then does all the work in response to the user's answer in that page. The problem then is to pass the object that the new ASPX page needs to do work on in response to the user's response.
I'm sure there are great solutions using Ajax or jQuery but this is a fairly simple function that shouldn't take too long to develop, so that is kind of out of scope for this.
Instead I'll go with a solution where I know what the user will respond to the question before they click the button. (While silently muttering under my breath: "It's 2019 and there's no good way to fire up a yes/no dialog from code behind in a .Net web project...". I need to get back to not working with web).

How to validate controls inside editform template of ASPxGridView?

I have an ASPxGridView with edit form template and some bound controls inside. After update I want to validate, check the values in controls on server side. As far as I could find this is not possible. DevExpress recommends subscribing to the RowUpdating event, but this is plain wrong. Useless as is very much of their so called support.
The problem is, that if controls contains some invalid text and it raises an exception somewhere long before RowUpdating and it gets eaten by devexpress. All it comes back to client is some message like "Input string was not in a correct format".
I want to validate input controls on the server side.
And yes, I do row validating also, but this is useful only for validating business logic.
So, how to validate controls that are bound inside EditForm template on server side?
Could you please clarify? You want to validate the values after you update or actually before you write the values to the database or each control individually as it loses focus before you can initiate the update? If it is necessary to do server side validation then I would recommend doing it in the RowUpdating and RowInserting server side event handlers as was recommended by DevExpress. Why do you think this is wrong? You can validate each of the bound controls' values in the e.NewValues collection of grid's Updating and Inserting events. If any of the values do not pass validation you can cancel the update/insert action. Could you outline your desired workflow in a little more detail?
A previous poster said a hack was necessary, putting a container inside the edit form template, which is not true. You can use the edit form template itself via the .NamingContainer of any control in the edit form template. Put your validation routine in the server side _Validation event handler of the specific controls.
You can evaluate the template controls as a group:
EditFormValid = ASPxEdit
.AreEditorsValid(myGrid.FindEditFormTemplateControl("myControl")
.NamingContainer);
Or you can update a class variable during each control's validation routine
public class foo
{
bool EditFormValid = true;
.
.
.
void myControl_Validation(object sender, ValidationEventArgs e)
{
EditFormValid = EditFormValid && myControl.IsValid;
}
void myGrid_RowUpdating(object sender, ASPxDataUpdatingEventArgs e)
{
If(EditFormValid)
{
.
.
.
}
else e.Cancel = true;
}
}
I have found DevExpress extremely effective and flexible. However the flexibility can be a double edge sword as there are many ways to almost do everything you need most of the time but usually one way to do everything you need all of the time. A developer can easily build on top of what works in one instance but isn't necessarily right/best practice and get to a point where they have coded into a corner as they continue to build upon a project.
If you can provide more specifics, so can I.
As far as I know this is not possible to do. Devexpress controls leave a lot to wish for. There is no way to check if validation was successful. Clearly a big issue.
What you can do is to run validation again with ASPxEdit.AreEditorsValid(). But for this you would have to do a little hack (as always with devexpress).
Put a container inside your edit form, a simple div with runat="server" and ID would do. This is your container.
Than get his div with FindEditFormTemplate() and use it in ASPxEdit.AreDitorsValid().
This workaround has drawbacks:
clutters your aspx code with unnecessary elements
page execution on server side is slower
page rendering on browser side is slower
ValidateEditorsIncontainer() runs validation again so there is a big
performance hit
All of the above are trademarks of DevExpress controls. But look at it from the bright side. Their grid sometimes takes up to five unnnecesary server and database roundtrips just to start editing.

Prevent Duplicate Insertion on DB When page refresh - Asp.net

(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).

How can I do <form method="get"> in ASP.Net for a search form?

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();

Modifying the HTML of a page before it is sent to the client

I need to catch the HTML of a ASP.NET just before it is being sent to the client in order to do last minute string manipulations on it, and then send the modified version to the client.
e.g.
The Page is loaded
Every control has been rendered correctly
The Full html of the page is ready to be transferred back to the client
Is there a way to that in ASP.NET?
You can override the Render method of your page. Then call the base implementation and supply your HtmlTextWriter object. Here is an example
protected override void Render(HtmlTextWriter writer)
{
StringWriter output = new StringWriter();
base.Render(new HtmlTextWriter(output));
//This is the rendered HTML of your page. Feel free to manipulate it.
string outputAsString = output.ToString();
writer.Write(outputAsString);
}
You can use a HTTPModule to change the html. Here is a sample.
Using the answer of Atanas Korchev for some days, I discovered that I get JavaScript errors similar to:
"The message received from the server could not be parsed"
When using this in conjunction with an ASP.NET Ajax UpdatePanel control. The reason is described in this blog post.
Basically the UpdatePanel seems to be critical about the exact length of the rendered string being constant. I.e. if you change the string and keep the length, it succeeds, if you change the text so that the string length changes, the above JavaScript error occurs.
My not-perfect-but-working solution was to assume the UpdatePanel always does a POST and filter that away:
protected override void Render(HtmlTextWriter writer)
{
if (IsPostBack || IsCallback)
{
base.Render(writer);
}
else
{
using (var output = new StringWriter())
{
base.Render(new HtmlTextWriter(output));
var outputAsString = output.ToString();
outputAsString = doSomeManipulation(outputAsString);
writer.Write(outputAsString);
}
}
}
This works in my scenario but has some drawbacks that may not work for your scenario:
Upon postbacks, no strings are changed.
The string that the user sees therefore is the unmanipulated one
The UpdatePanel may fire for NON-postbacks, too.
Still, I hope this helps others who discover a similar issue. Also, see this article discussing UpdatePanel and Page.Render in more details.
Take a look at the sequence of events in the ASP.NET page's lifecycle. Here's one page that lists the events. It's possible you could find an event to handle that's late enough in the page's lifecycle to make your changes, but still get those changes rendered.
If not, you could always write an HttpModule that processes the HTTP response after the page itself has finished rendering.
Obviously it will be much more efficient if you can coax the desired markup out of ASP.Net in the first place.
With that in mind, have you considered using Control Adapters? They will allow you to over-ride how each of your controls render in the first place, rather than having to modify the string later.
I don't think there is a specific event from the page that you can hook into; here is the ASP.Net lifecycle: http://msdn.microsoft.com/en-us/library/ms178472.aspx
You may want to consider hooking into the prerender event to 'adjust' the values of the controls, or perform some client side edits/callbacks.

Resources