catch user activity within webbrowser or watin - c#

Is there any way to detect all the possible user activities within a WebBrowser and return a custom Event? For example: User clicks on "search" button, return "SearchButtonClicked" custom Event.
It would be something like, logging of all the activity that user does, stored in a sequence and could be automated once he wanted.
Edit: I do not own the webpage. I am trying to make an application to automate some searching on google.

After some research, I discovered the HtmlElementEventHandler.
Example:
webBrowser1.Document.GetElementById("MainContent_LoginButton").Click += new HtmlElementEventHandler(test);
// some code...
public void test(object sender, HtmlElementEventArgs e)
{
MessageBox.Show("Clicked login button");
}

Wow, it's going to be quite a bandwidth intensive application... :) You might consider a framework like jQuery to attach events to all anchors and button-type inputs to perform AJAX calls to your server, for example. So you might have something along the lines of the following process:
Include a JS file on all your pages to do something like the following:
$(document).ready(function () {
var trackUserActivity = function(elementId, elementText) {
$.ajax({
type: "POST",
url: "url/TrackUserActivity",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({
ElementId: elementId,
ElementText: elementText
}),
success: function (result) {
// do something if call was successful
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// do something if an error occurred
}
});
};
$("a, input[type=\"button\"], input[type=\"submit\"]").click(function() {
trackUserActivity($(this).attr("id"), $(this).text());
});
});
Create a Web Method that can be called via AJAX to track the user activity:
[WebMethod]
public static void TrackUserActivity(string ElementId, string ElementText)
{
// Implement your user activity tracking logic, like saving it in a database
}
After your OP edit, you don't own the application, so this won't work. I'm keeping the answer here for someone in the future who might have a similar need.

See types of HtmlElementEventHandler:
http://msdn.microsoft.com/en-us/library/system.windows.forms.htmlelement_events%28v=vs.110%29.aspx
Use this event handler for knowing event occured. On event occured, get the element details, tag details and log in the file with the type of event.
See usage of downcasting required when using HtmlElementEventHandler
http://www.hanselman.com/blog/BackToBasicsThisIsNotTheObjectYoureLookingwaitOhItIsTheObject.aspx.
When you want to replay action, you may run logged events in sequence, after extracting tag name and value fields.

Related

Sending $ajax via jQuery to C# codebehind not working

I am having unexplained behavior when I post from jquery using ajax to C#.
1) The main page is called not the method I am requesting in jQuery.
To work around this I simply put an if in the page load so that if a particular item is in the querystring it will trigger a series of commands. It does hit that if statement and runs the code perfectly fine. There are some methods that do things like change a color on the map. These never actually happen. I can set a label and it will pass right over it but the label remains unset.
2) strangely enough.... my page has a timer with a refresh on it. It refreshes the page and now the changes are processed.
Here is the way I am calling my method in jQUery:
function mycmethod(param)
{
//alert(precinct);
$.ajax({
url: "myPage.aspx/someMethod",
type: 'POST',
data: "params=" + param,
success: function iGotData(responseJSON) {
// alert("Worked");
},
error: function (xhr, status, errorThrown) {
console.log("Error: " + errorThrown);
console.log("Status: " + status);
console.log(xhr);
alert("Didnt work:" + errorThrown);
},
})
};
It was originally set to async: true but that didn't make a difference.
The method its not calling on load is:
[WebMethod][ScriptMethod]
public Boolean someMethod(string param)
{
setFeatures();
GenerateMap();
return true;
}
I doubt its relevant but I am calling a jquery call with over mouse over of a specific element. That jquery calls a function which calls a asmx web service that returns some jSON. I am calling the mycmethod after the JSON is returned.
Why is my UI elements not responding until the page refreshes. If not, is there a way I can force a refresh like the timer does?
[WebMethods] methods should be declared as static.
I've also found that you might need to specify the content type in your ajax call:
contentType: "application/json; charset=utf-8"
Also, your data option looks suspicious. Maybe you should append it to the url option:
url: "myPage.aspx/someMethod?params" + parm
or, more ideally, send it as either a JSON object or a JSON string:
data: {
params: param
}
or
data: JSON.stringify({
params: param
})
If I understand you correctly, you're loading the page, then calling the server via ajax and expecting the server to change UI elements of the currently loaded page.
It doesn't work like that, unfortunately. Once you've served the page, the server itself cannot manipulate that page without doing a refresh/post back (or something along those lines).
If you want to update the UI without doing a refresh/post back you can have your WebMethod return HTML, and your jQuery success method can update the relevant controls.
Alternatively you could use jQuery's .get() to retrieve a fresh copy of the page via ajax, and update your current page like that. (although it's less efficient)

Is there a way to capture JavaScript PageMethods calls with jQuery? (To show Loading Screen)

I'd like to know if someone knows a way, using jQuery, to capture PageMethods calls made from JavaScript in order to show a loading screen when a call begins and to hide it when it ends (when the PageMethod responds).
I know there are ways to capture ajax calls when they are made like this:
$.ajax({
type: "POST",
url: "PageName.aspx/MethodName",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Do something interesting here.
}
});
but is there a way to capture them and then do something when they are called like this?
JavaScript
PageMethods.serverSideMethod(responseFromServer);
CodeBehind
[WebMethod()]
public static string serverSideMethod()
{
return response;
}
I'm using jQuery 1.9.2, programming in C# and need this script to be compatible with IE6.
it's almost the same,use this url in jQuery
url: "PageName.aspx/serverSideMethod",
insert your method name without parantheses,it should work.
Edit:
you can capture start and complete event with using these ajax events:
$.ajax({
beforeSend: function(){
// Handle the beforeSend event
},
complete: function(){
// Handle the complete event
}
// ......
});
Then you can show or hide whatever you want... here is the full documentation: http://api.jquery.com/Ajax_Events/
You can just show the loading message right after or before the PageMethod call and then hide it in the callback:
PageMethods.serverSideMethod(responseFromServer);
//Show loading using jQuery Here
function responseFromServer(results){
//process results
//hide loading using jQuery
}
UPDATE:
Have you tried Sys.WebForms.PageRequestManager beginRequest Event and endRequest Event: http://msdn.microsoft.com/en-us/library/bb397432(v=vs.100).aspx and http://msdn.microsoft.com/en-us/library/bb383810(v=vs.100).aspx

populate dropdownlist on button click using jquery

In my application ,I have a dropdownlist which is to be populated on button click.I tried some code which is working fine on document.ready but its not working on button click..
$(document).ready(function () {
$("#<%=btn.ClientID %>").bind('click',function () {
//
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "gridpaging.aspx/binddropdown",
data: "{}",
dataType: "json",
success: function (data) {
$.each(data.d, function (key, value) {
$("#ddl").append($("<option> </option>").val(value.UserId).html(value.UserName));
});
//
},
error: function (result) {
alert("Error occured");
}
});
});
});
Please let me know where i went wrong..Thanks in advance..
It looks like you are mixing up two techniques here. One is ejs: <%=btn.ClientID %>, which is a templating engine to serve up dynamic content. The other is your jquery. What may solve your issue is to add a class to that button, rather than relying on your btn.ClientID, and then use $(".myClass").bind('click', function() ...
See if that solves your problem. If not, I'll need a bit more information. Is the ejs being compiled on the server side or on the client side? Are you using backbone or some kind of front end framework that's compiling the ejs?
yourdeveloperfriend is almost right, except <%=btn.ClientID %> is not ejs, but asp.net snippet which is most probably used in the wrong place. I can imaging only one scenario in which this could work, and that is when this JS code is located in you aspx file, but most probably you have it in a separate js file. So do what yourdeveloperfriend said, and put a class on the button, and use that as a selector in your JS.
I also had this same issue and solved it by changing the id setting
$("#ddl")
to
$('#<%=ddl.ClientID%>')

FireFox and IE9 tries to download or show json-response instead of letting javascript parse it

Update
My problem was that I used event.preventDefault() instead of return false to hinder the form from posting normally. FF and IE didn't like that and broke the JS by that line. I removed that and appended return false at the end and this solved the problem. Thanks to Darin Dimitrov for the extensive checklist.
Original question
I'm using ASP.NET MVC3 and jquery ajax to post json-data to the server and receive a response. However, when I'm using Chrome it reads the json-response normally, updating the divs that I want etc. With IE and FF it doesn't work though. They read just the response and shows only that on the page.
I saw some other threads mentioning to define the mime type as "text/plain". This changed the previous behavior of prompting the user to download the json-response instead.
This is the javascript for making the post:
$.ajax({
url: $("#formRegister").attr("action"),
type: 'POST',
data: JSON.stringify(user),
dataType: 'json',
contentType: 'application/json, charset=utf-8',
traditional: true,
success: function (data) {
alertMessage(data.Message);
},
error: function () {
}
});
This is the ActionMethod receiving the call and returning a JsonResponse:
[HttpPost]
public JsonResult Register(UserRegisterPackage package)
{
ClientAlert alert = new ClientAlert();
if (package.Password != null)
{
//bool success = Removed for simplicity's sake.
bool success = true;
if (success)
{
alert.Message = "Success!";
}
else
{
alert.Message = "Failed to register";
}
}
else
{
alert.Message = "You need to enter a password!";
}
return Json(alert, "text/plain");
}
As I said, when the content type is defined as text/plain the browser shows only the response and when it's not defined it prompts the user to download the json-response instead.
With FF I seem to get an error about:
"event is not defined
event.preventDefault(); "
This could have something to do with the error.. but I need to prevent the form from posting normally. Is this done differently in FF or IE?
Any ideas?
Things to try:
If this $.ajax call is made inside the .click or .submit handler of some anchor or <form> make sure you return false; at the end in order to cancel the default behavior and leave time for your AJAX request to execute. The attr('action') that you are using leaves me to believe that this is the case.
Remove traditional: true parameter, you are sending a JSON request => it is irrelevant.
Make sure there aren't some other javascript errors on your page as they might stop js execution and proceed into normal form submission
Remove all text/plain from your server if you intend to return JSON. It's meaningless to do something like this and it's definitely not where your problem comes from. Simply use return Json(alert);.
So if you are AJAXifying a form you don't even need any JSON requests, simply:
$('#formRegister').submit(function() {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (data) {
alertMessage(data.Message);
},
error: function () {
}
});
return false;
});
and if you intend to send JSON requests then your code seems fine, jsu make sure there aren't some other JS errors.
I faced the same problem where "JsonRequestBehavior.AllowGet" worked great on chrome, but fails on IE. i tried many formats, but below is the only one worked for IE.
return Json(additionalData, "text/html")
I encountered this when using an older version of jQuery.Validate, something to do with a bug in there setting the incorrect dataType.
Make sure you are using the latest version of jQuery.validate
return Json(alert, "text/plain");
Usually Json(alert) should be enough. Can you try with application/json; charset=utf-8 as a content type?

Saving changes to a jQuery sortable table

I have a table where the users are allowed to drag and drop rows in the order they want, and then save them. I have no problem with getting the drag and drop part to work. It's the saving I'm having issues with. I'm sending an Ajax call to a web service which will then make the save. I can't seem to actually catch the request in the web service though.
My JavaScript function looks like so:
$(document).ready(
function () {
$(".sortable").sortable({
update: function () {
serial = $('.sortable').sortable('serialize');
$.ajax({
url: "MyWebService.asmx/SortTable",
type: "post",
data: serial,
error: function () {
alert("theres an error with AJAX");
}
});
}
});
});
The JSON string looks fine from what Firebug is showing me. The web service function is like so:
[WebMethod]
public string SortTable(String[] rows)
{
//SaveChanges();
return "Called!";
}
When I put a breakpoint in there, it never gets hit. When there are no arguments in the function though, it will get hit. I've tried replacing "String[]" with "object" and it still doesn't get hit, which I find odd. What is going on here?
You might need to decorate your web service with the [ScriptService] attribute in order to allow client scripts to invoke it. Also if you are sending a JSON request you need to specify the content type. Another remark is about sending the request as an actual JSON object which could be achieved using the JSON.stringify method (maybe the $('.sortable').sortable('serialize') call already does this, I am not familiar, you just need to ensure that the POSTed value looks like this: [ 'row1', 'row2', ... ]):
$.ajax({
url: 'MyWebService.asmx/SortTable',
type: 'post',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify([ 'row1', 'row2', 'row3' ]),
error: function () {
alert('theres an error with AJAX');
}
});

Categories