Got a very weird problem.
I just successfully implemented a simple ajax validation on my site (Yey!). I hooked up the validation to the OnFocusOut event of every textbox via backcode, which runs perfectly.
The weird bug happens when,on the same page , I call the exact same method and pass the same parameters via a validate() method or add the attribute OnFocusOut on document.ready() . I keep getting a status of 500.
I was able to verify that the server side method isn't successfully called when using validate() but runs when OnFocusOut is triggered.
WebServiceAdapter
function ValueChanged(target, validationDiv,valueType) {
targetControl = document.getElementById(validationDiv);
// Added this part because I'm guessting a null is causing it
var str = (target.value === '') ? " " : target.value;
switch (valueType) {
case "email":
webServiceAdapter.EmailExist(str);
break;
case "screenName":
webServiceAdapter.ValidScreenName(str);
break;
case "changePassword":
webServiceAdapter.PasswordCorrect(str);
break;
}
Adding OnFocusOut backcode - WORKS
txtEmail.Attributes.Add("onfocusout", "ValueChanged(this,'"+Email.ClientID+"','email')");
Adding OnFocusOut jquery - DOES NOT WORK
$("#<%=txtEmail.ClientID%>").attr("onfocusout", "ValueChanged('<%=txtEmail.ClientID%>', '<%=Email.ClientID%>', 'email')");
Calling via validate() method - DOES NOT WORK
ValueChanged('<%=txtEmail.ClientID%>', '<%=Email.ClientID%>', 'email');
Edit:
I'm also getting this error "An error occurred: Invalid web service call, missing value for parameter: 'email'." After invoking validate()
Solved the problem.
Quite embarrassing really. It was a "common sense bug".
ValueChanged() was expecting an object as the first parameter - this is what the backcode is doing by using "this". For the call from validate(), i was using the ID.
Related
I'm trying to have a contact form (MVC )that will reload the View if it fails validation. That works. However if you go back to the page and correct your error, the ModelState is still false on submit so it's just reloading the page.
I tried doing ModelState.Clear before the return, but that will clear the errors. I need a way to show the error, and THEN clear the model, but ofcourse I cant use that method after returning.
My code below:
public ActionResult Index(ContactFormViewModel model, string inputFirstName, string inputLastName, string inputEmail, string inputMessage)
{
if (ModelState.IsValid)
{
return View("Success");
}
//reload page and show validation errors
else
{
return View(model);
}
}
For example, in my Model, I have a regex on the Message field with error message. If I first type something that is not allowed, ModelState is false and returns View (correct). However, go back to the form and correct issue, ModelState should now be true but it is still false.
If I do
else
{
ModelState.Clear()
return View(model);
}
then the page reloads with no error messages. This is not ideal.
How do I get it so that the error message is displayed and then the modelState is clear.
I tried ContactFormViewModel cmModel = new ContactFormViewModel() but this had the same result.
Try something like this:
return View(new ContactFormViewModel());
Create a new object and pass it to the view.
After debugging, I found that the ModelState.IsValid was correctly showing as not valid because actually, the string I entered in the inputMessage did not satisfy the regex.
The answer had nothing to do with the model at all.
I am toying with Ajax-Enabled WCF services. So far I've managed to create and consume my service with a small client application. However while reading the "How-to" page on the msdn website, I've came accross this piece of code :
function Button1_onclick() {
var service = new SandwichServices.CostService();
service.CostOfSandwiches(3, onSuccess, null, null);
}
function onSuccess(result) {
alert(result);
}
and I fail to understand (or even find information about) the null, null parameters when calling the function. 3 is the parameter you want to pass to the service function, onSuccess is the function that is called on a successfull callback but what are those 2 null parameters ?
The last two parameters refer to onFailure and Usercontext respectively for below mentioned question.
service.CostOfSandwiches(3, onSuccess, null, null);
OnFailure : As the name suggest, if ajax call fails because of network issue, server error, timeout etc.., function passed here as argument will invoked.
UserContext: Generally all ajax call (I mean this[WCF Ajax] is too dependent on ajax call) uses this parameter. Because, there is a main method that call $.ajax, in your case it is Button1_onclick. So upto this point all variables defined will not be available in callbacks ( success or failure), because these are called back when ajax call completes, but to make those call aware of previously defined variable, context option is used to pass them.
Example:
function Button1_onclick() {
var service = new SandwichServices.CostService();
var some_var = "someval"; // on successcallback if you are trying to access this, it will show error.
service.CostOfSandwiches(3, onSuccess, null, null);
}
To use this in success callback , you have to pass that as usercontext object -- like this service.CostOfSandwiches(3, onSuccess, null, some_var);
OnSuccessMethod -
function onSuccess(result,usctx,methodname)
{
if (usctx == "someval")
{
alert(result);
}
}
For more info on context option in general ajax sense , refer this - How to pass context in jquery ajax success callback function
They are callbacks for sucess, error, and userContext. You can read a bit more here under the "Accessing WCF web services" section.
I have read here that any ASP.NET validator has a property called: isvalid. This property can be used in client side to check if the validator successfully passed the validation or not.
I tried to access this property as following but for some reason the code fail:
alert(document.getElementById("validator_clientID").isvalid);
Do you have any idea why this is not working?
I found same !
try this document.getElementById('XXX').Validators[0].isvalid It's working for me
I don't think the isvalid works on a validator control directly as this is a server side validation function. You can fire a validator check for the current page or validation group using the client side javascript function Page_ClientValidate. You can optionally specify a validation group name a parameter. This will return true if all the validation passes.
You can also look at more available client-side functions and how they map to the server side functions on MSDN at:
http://msdn.microsoft.com/en-us/library/yb52a4x0.aspx
Kindly have a look at the solution below that iterates through all validators and display validators which are invalid at the client side
var varray=new Array();
for (var i = 0; i < Page_Validators.length; i++)
{
if(!Page_Validators[i].isvalid)
{
varray.push(Page_Validators[i])
}
}
varray;
You can paste this code in console to get invalid validators
Remember to call
IsValid
instead
isvalid
(may vary)
On client side Javascript:
var controlIsValid = this.document.getElementById("validatorID").attributes.isvalid.value;
If I want to call a server function from JavaScript to retrieve a name of a person from a database (just as an example)... and I went...
name = myServices.getName(userId);
If I have a script manager with a service reference to a .asmx file that has the web method getName( int userId ) {} then this function should be called properly and would, eventually, return the name for that userId.
Unfortunately, I want to do...
name = myServices.getName(userId);
alert(name);
however, when doing ASP.NET AJAX, it would call the web method and continue executing before waiting for a response from the server (which I understand is the point of AJAX, to stop the browser from freezing while waiting for data)
I need to get the name back from the server before I can continue executing... How can I approach this to fix this issue?
There is a method you can add as a parameter to the service method that will call the method on success where you can do other stuff.
For example:
function test() {
PageMethods.MyMethod("name", OnMyMethodComplete);
}
function OnMyMethodComplete(result, userContext, methodName) {
alert(result);
}
If you want to call a Web method synchronously, you'll need to set up the request manually and use a Sys.Net.XMLHttpSyncExecutor.
Here's an example (see ExecuteSynchronously function).
For a JavaScript solution, you could loop until name has a value. Adjust time-based on latency to keep app responsive
var time = 100;
window.setTimeout(name == '' ? wait : continue, time);
function wait() {
window.setTimeout(name == '' ? wait : continue, time);
}
function continue() {
//code having to do with name
alert(name);
}
Congratulations! You've taken your first step into a larger asynchronous world. I'd definitely go with using the callbacks that CSharpAtl suggested.
I'm having a problem with some code I've written. I've had to anonymize it, but I can give the problem. This javascript runs inside an iframe, and is part of an object that gets instantiated. The problem in particular is that I get a repeating error every time that "Type 'Object' Cannot be converted to type 'Function'" in the invoke() call. However, in the IE8 developer addon, checking the typeof of the function I pass (this.AJAXCallback), it clearly says that it's a function being passed. Is there any particular reason this error might be occurring?
MyObject.prototype.AJAXCallback=function(Data, e){
//snip
};
MyObject.prototype.Init=function(){
var a = window.top.window.Sys.Net.WebServiceProxy.invoke('/Data.asmx', 'GetData', false, { "IDCode":0 }, this.AJAXCallback, null);
//snip
};
I found the problem, and it doesn't seem to be on my part. I disabled debugging in the web.config file, and the error stopped. It also came back after debug was turned on, so I think it's safe to say that the debug code didn't work as well with what I wrote as the non-debug code did. In particular, it was one of the scriptmanager's JS files.
It may be giving issues because the Callback is a prototype. Have you tried wrapping the callback in an anonymous function call.
MyObject.prototype.Init=function(){
var a = window.top.window.Sys.Net.WebServiceProxy.invoke('/Data.asmx', 'GetData', false, { "IDCode":0 }, function(data,e) {
this.AJAXCallback(data,e);
}, null);
//snip
};