سؤال

I'm trying to do Client-Side validation via a javascript function. I have an ASP.NET c# page, that successfully calls a WebMethod (from pages code behind) to validate data entered is accessible to the user. I have a textbox with AJAX AutoCompleteExtender and this works fine. I have CustomValidator that I'm trying to call a javascript function to validate the data. The webmethod (which pulls from SQL database) is executing and returning data as expected. The Javascript is executing the webmethod. The issue is the PageMethods is using an 'OnSuccess' function (a nested function from the javascript function being called) however from the OnScuess function I can't set the args.IsValid = true/false. I can set this property in the original function but in order to do that I need both the args.Value and result from the OnSuccess in order to evaluate if it is valid. Both are not accessible from each other. I've tried hiddenfields to set the value to evaluate, I've tried 'Global' variables in JavaScript. Nothing seems to give me the desired results. Both the hidden field as well as the 'Global' variable is not getting set before the evaluation to set the args.IsValid. Can someone please help. I can't believe how difficult such a simple task has become. The only way I'm getting the validation error message to show up is if I manually set the args.IsValid and issue an alert("doesn't mater what I put in here") at the bottom of the javascript primary function. I don't want an alert, I just want a message displayed next to my text box. Eventually this will go into a gridview (will have input boxes on each item row to allow multiple row edits at once.

I know a simple solution would be to have a dropdownlist but and serverside validation as well however this is not what I need.

Here is my javascript function

function pmValidateGLAccount(oSrc, args) {
    var GLIsValid;
    PageMethods.ValidateGLAccountAccess(args.Value, OnSuccess);
    function OnSuccess(result) {
        // I NEED TO DETERMINE IF IS VALID BUT SET THE args.IsValid after the process leaves this nested function
        if (args.Value != result) {
            GLIsValid = false;
        }
        else {
            GLIsValid = true;
        };
    };// THIS IS THE END OF THE ONSUCCESS FUNCTION
    //args.IsValid = false; //THIS IS WHERE WE NEED TO SET THE IsValid

} // THIS IS THE END OF THE pmValidateGLAccount FUNCTION

here is my CustomValidator

<asp:CustomValidator ID="CustomValidator1" 
runat="server" 
ControlToValidate="TextBox1"  
ValidationGroup="vg_test" 
ClientValidationFunction="pmValidateGLAccount" 
ErrorMessage="Error: Please Enter an Account Number from the list" 
Display="Dynamic"></asp:CustomValidator>

here is my webmethod

[System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()]
public static string ValidateGLAccountAccess(string GLAccountNum)
{

    string RetValue = string.Empty;
    string CurUser = HttpContext.Current.User.Identity.Name.ToString();
    string CurUserRemoveDomain = string.Empty;
    int i = CurUser.IndexOf("\\");
    if (i != -1)
    {
        CurUserRemoveDomain = CurUser.ToLower().Replace(Resources.AppSettings.ActiveDirectoryDomain.ToString().ToLower() + "\\", "");
        CurUser = CurUserRemoveDomain;
    }

    using (SqlConnection conn = new SqlConnection())
    {
        conn.ConnectionString = ConfigurationManager.ConnectionStrings["CustDBConn"].ConnectionString;
        using (SqlCommand cmd = new SqlCommand("MySproc", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@SearchString", GLAccountNum);
            cmd.Parameters.AddWithValue("@UserName", CurUser);
            cmd.Connection = conn;
            conn.Open();
            RetValue = (string)cmd.ExecuteScalar();
            conn.Close();
        }
    }
    return RetValue;
}
هل كانت مفيدة؟

المحلول

Ok so for those that are still fighting with a means of a synchronous client-side validation solution. I finally got the solution working. I was reluctant to experiment with jQuery, but wish I would have days ago.

What I was trying to accomplish was a textbox autocomplete that would pass the username to the database and begin returning data specific for that user. Then to prevent any input in the textbox other than from the permitted autocomplete list, I used the CustomValidator with jQuery. What this did is take the final input string along with the username and passed it to the database. If the database returned a record with the matching string, the selection was valid; if not, the selection is marked as invalid.

I fought for so long with this, I wanted to give others an 'as complete as possible' guide. For those that have not used jQuery, neither had I prior to this and that portion took the least amount of time to come up with this solution. I hope this helps someone out there.

Here is exactly what I did:

  1. Downloaded the jQuery script and placed it in my scripts folder. Added a reference to the jQuery in my MasterPage.Master header section. Modified the ScriptManager (in the body) to EnablePageMethods.

    <script type="text/javascript" src="/scripts/jquery-1.4.2.js"></script> 
    
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
    </asp:ScriptManager>
    
  2. Added the JavaScript just inside my content place holder in TextBoxAutoFill.aspx.

    <script type="text/javascript">
        function pmValidateGLAccount(oSrc, args) {
            $.ajax({
                type: "POST",
                async: false,
                url: "TextBoxAutoFill.aspx/ValidateGLAccountAccess",
                data: "{ GLAccountNum: " + "'" + args.Value + "' }",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (response) { args.IsValid = response.d; }
            });
        }; 
    </script>
    
  3. Created my TextBox, AutoCompleteExtender and CustomValidator

    <asp:TextBox TabIndex="1" autocomplete="off" ID="TextBox1" runat="server" Width="250px" ValidationGroup="vg_test"></asp:TextBox>
     <asp:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" 
         runat="server" 
         EnableCaching="true"
         CompletionSetCount="10"
         ShowOnlycurrentWordInCompletionListItem="true"
         CompletionInterval="500" 
         CompletionListCssClass="AJAXAutosuggestTextBox" 
         DelimiterCharacters="" 
         Enabled="True" 
         ServiceMethod="GetAccountNumbers" 
         TargetControlID="TextBox1" 
         MinimumPrefixLength="4"
         >
    </asp:AutoCompleteExtender>
    <asp:CustomValidator ID="CustomValidator1" 
        runat="server" 
        ControlToValidate="TextBox1"  
        ValidationGroup="vg_test" 
        ClientValidationFunction="pmValidateGLAccount" 
        ErrorMessage="Error: Please enter an account number from the list" 
        Display="Dynamic"></asp:CustomValidator>
    
  4. Added the WebMethod for my AutoCompleteExtender (This is in the TestBoxAutoFill.aspx.cs file)

    [System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()]
    public static List<string> GetAccountNumbers(string prefixText, int count)
    {
        string CurUser = HttpContext.Current.User.Identity.Name.ToString();
        string CurUserRemoveDomain = string.Empty;
        int i = CurUser.IndexOf("\\");
        if (i != -1)
        {
            CurUserRemoveDomain = CurUser.ToLower().Replace(Resources.AppSettings.ActiveDirectoryDomain.ToString().ToLower() + "\\", "");
            CurUser = CurUserRemoveDomain;
        }
    
        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["CustDBConn"].ConnectionString;
            using (SqlCommand cmd = new SqlCommand("SP_PCard_Get_AutoCompleteAccountNumbers", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@RecCount", count);
                cmd.Parameters.AddWithValue("@SearchString", prefixText);
                cmd.Parameters.AddWithValue("@UserName", CurUser);
                cmd.Connection = conn;
                conn.Open();
                List<string> AccountNumbers = new List<string>();
                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        AccountNumbers.Add(sdr["ACTNUMST"].ToString());
                    }
                }
                conn.Close();
                return AccountNumbers;
            }
        }
    }
    
  5. Added the WebMethod for validation (This is in the TestBoxAutoFill.aspx.cs file)

    [System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethod()]
    public static bool ValidateGLAccountAccess(string GLAccountNum)
    {
        string RetValue = string.Empty;
        string CurUser = HttpContext.Current.User.Identity.Name.ToString();
        string CurUserRemoveDomain = string.Empty;
        int i = CurUser.IndexOf("\\");
        if (i != -1)
        {
            CurUserRemoveDomain = CurUser.ToLower().Replace(Resources.AppSettings.ActiveDirectoryDomain.ToString().ToLower() + "\\", "");
            CurUser = CurUserRemoveDomain;
        }
        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["CustDBConn"].ConnectionString;
            using (SqlCommand cmd = new SqlCommand("SP_PCard_Get_SelectedGLAcountNumber", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@SearchString", GLAccountNum);
                cmd.Parameters.AddWithValue("@UserName", CurUser);
                cmd.Connection = conn;
                conn.Open();
                RetValue = (string)cmd.ExecuteScalar();
                conn.Close();
            }
        }
        Boolean myVarBool = false;
        if (RetValue == GLAccountNum)
        {
            myVarBool = true;
        }
        return myVarBool;
    }
    

نصائح أخرى

Hmm I didn't play much with .NET C# but usually i just using JQuery validation and AJAX for web apps.

I try to answer your question, i can't try..but might be will little bit help :

  1. please make sure the PageMethods.ValidateGLAccountAccess(args.Value, OnSuccess); return right result?

  2. Try this and debug it with alert(args.IsValid) after you try this code :

    function pmValidateGLAccount(oSrc, args) {
    var GLIsValid;
    args.IsValid =false;
    PageMethods.ValidateGLAccountAccess(args.Value, OnSuccess);
    function OnSuccess(result) {            
        if (args.Value != result) {
            GLIsValid = false; // or you don't need this
            args.IsValid= false;
            alert(args.IsValid);
        }
        else {
            GLIsValid = false; // or you don't need this
            args.IsValid= true;
            alert(args.IsValid);
        }
    } 
    

    }

  3. Sorry if that not your mean, but if you need to get it..you can put the "var GLIsValid;" outside the function as global variable..if you defined on that function it's mean just can be access on that function wrap. THank you

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top