Your problem is that message box from validation summary is shown only on client validation stage in and is called from ValidationSummaryOnSubmit
function which is called from Page_ClientValidate
function:
function Page_ClientValidate(validationGroup) {
Page_InvalidControlToBeFocused = null;
if (typeof(Page_Validators) == "undefined") {
return true;
}
var i;
for (i = 0; i < Page_Validators.length; i++) {
ValidatorValidate(Page_Validators[i], validationGroup, null);
}
ValidatorUpdateIsValid();
ValidationSummaryOnSubmit(validationGroup);
Page_BlockSubmit = !Page_IsValid;
return Page_IsValid;
}
Here is the snippet from ValidationSummaryOnSubmit
which creates a list of error messages and shows alert
:
if (summary.showmessagebox == "True") {
s = "";
if (typeof(summary.headertext) == "string") {
s += summary.headertext + "\r\n";
}
var lastValIndex = Page_Validators.length - 1;
for (i=0; i<=lastValIndex; i++) {
if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") {
switch (summary.displaymode) {
case "BulletList":
default:
s += "- " + Page_Validators[i].errormessage;
if (i < lastValIndex) {
s += "\r\n";
}
break;
// Other cases omitted to shorten the snippet
}
}
}
alert(s);
}
The only way to make it work consistently is to add client validation function for your custom validator and expose the server side validation function as a web service method.
The first step would be to add ClientValidationFunction
:
<asp:CustomValidator ID="validProductCode" runat="server"
ControlToValidate="txtProductCode"
OnServerValidate="ValidateProductCode"
ClientValidationFunction="validateProductCode"
ErrorMessage="The product code entered is invalid"
Display="None"
ValidationGroup="IWS"/>
Second step is to modify validation method on the server side:
protected void ValidateProductCode(object source, ServerValidateEventArgs args)
{
args.IsValid = ValidateProductCode(ddlSiteId.SelectedValue, txtProductCode.Text);
}
// This method would be called both from the client and server side
[WebMethod]
public static bool ValidateProductCode(string siteId, string productCode)
{
try
{
using (SqlConnection conn = new SqlConnection(GetConnection.GetConnectionString()))
using (SqlCommand sqlComm = new SqlCommand("PL_ProductCodes_FillScreen", conn))
{
sqlComm.Parameters.AddWithValue("@SiteID", siteId);
sqlComm.Parameters.AddWithValue("@ProductCode", productCode);
sqlComm.Parameters.AddWithValue("@IsOntext", 1);
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(sqlComm);
DataSet ds = new DataSet();
da.Fill(ds);
return ds.Tables[0].Rows.Count != 0;
}
}
catch (SqlException ex)
{
ExceptionHandling.SQLException(ex, constPageID, constIsSiteSpecific);
}
return false;
}
Third step is to define client script validation function and call the ValidateProductCode
method using JQuery.ajax
call. Please note that I'm not suggesting using PageMethods
here because in validator function we need to do a "synchronous" call to the server and the simple way is to use JQuery:
<script language="javascript">
function validateProductCode(sender, args) {
var txtProductCodeClientId = "<%= txtProductCode.ClientID %>";
var productCodeValue = ValidatorGetValue(txtProductCodeClientId);
var ddlSiteIdClientId = "<%= ddlSiteId.ClientID %>";
var ddlSiteIdValue = ValidatorGetValue(ddlSiteIdClientId);
var isValid;
var parameters = {
siteId: ddlSiteIdValue,
productCode: productCodeValue
};
$.ajax({
type: "POST",
async: false,
url: "<%= Page.ResolveUrl("~/<RELATIVE PATH TO YOUR PAGE>/ValidateProductCode") %>",
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
isValid = response.d;
},
error: function() {
isValid = false;
}
});
args.IsValid = isValid;
}
</script>
Be warned that this approach will make a call to the server whenever txtProductCode
will change its value and lose focus (i.e. onchange
event) but this will not automatically update a validation summary so no alert message will be shown. To avoid making such "redundant" calls to server you can clear the onchange
event handler for txtProductCode
input after the document been loaded.
A quick note if you are using FriendlyUrls:
To make it work you'll need to set FriendlyUrlSettings.AutoRedirectMode
to RedirectMode.Off
in your routes configuration.
If that's not an option then you'll need to setup asmx service, see Exposing Web Services to Client Script MSDN article.