Pull specific IDs from HTML code C# - c#

I am making a program that you can log into facebook, go to someone's wall and post on it. I have all of this working, if i manually enter in the ID that i go and find in the HTML for the textview box where you write the status and the Post button where you click to post. My problem is that the ID for this textbox and the post button changes every single time you go to the page or the page refreshes. So you cant just code in the ID to get it like thisHtmlElement element = browser.Document.GetElementById("some-ID"); I need to somehow parse the HTML code and pull out the specific IDs for the textview and the button every time the page refreshes. I have looked into html agility pack and it hasn't really helped me any. Can anyone help?
EDIT
Here is the line of code I am trying to get the ID out of for the text area where you post. You can see that it is just a random garble of letters and some numbers at the end. It changes every time you load the page. And I haven't looked at the facebook api would it help any?
<DIV class="innerWrap"><TEXTAREA aria-expanded="false" onkeydown='Bootloader.loadComponents(["control-textarea"], function() { TextAreaControl.getInstance(this) }.bind(this)); ' id="ujkzdk454" class="DOMControl_placeholder uiTextareaAutogrow input mentionsTextarea textInput" title="Write something..." role="textbox" aria-owns="typeahead_list_ujkzdk453" name="xhpc_message" autocomplete="off" aria-autocomplete="list" placeholder="Write something..." aria-label="Write something...">Write something...</TEXTAREA></DIV></DIV></DIV><INPUT

I agree you should probably be using the Facebook API but anyway, how about some thing like this with jquery?
var textarea = $('textarea', '.innerWrap');
var button = $('.innerWrap').next('input');
and if you still want the ids
var textareaId = textarea.attr('id')
var buttonId = button.attr('id')

Related

Invalid ViewState when using jQuery tabs

I have a fairly simple page with a set of jQuery tabs, the content of some is called via ajax. I also have a search box in the masterpage in my header.
When I open the tabbed page the search box works fine. However once I have clicked on one of the ajax tabs the search box fails to work with an "Invalid Viewstate" yellow screen of death.
I believe this is because the ajax page is replacing the __VIEWSTATE hidden input with its own.
How can I stop this behaviour?
UPDATE: I have noticed that the YSOD only appears in IE and Chrome, Firefox doesn't seem to have the same issue. Although how the browser influences the ViewState, I'm not sure.
UPDATE: I've put a cut down version of the site that shows the issue here: http://dropbox.com/s/7wqgjqqdorgp958/stackoverflow.zip
The reason of such behavior is that you getting content of the ajaxTab.aspx page asynchronously and paste it into another aspx page. So you getting two instances of hidden fields with __VIEWSTATE name and when page posted back to server theirs values are mixing (might depends on how browser process multiple controls with same name on submit). To resolve this you can put second tab's content into a frame:
<div id="tabs">
<ul>
<li>Default Tab</li>
<li>ajax Content</li>
</ul>
<div id="tabs-1">
<p>
To replicate the error:
<ul>
<li>First use the search box top right to search to prove that code is ok</li>
<li>Then click the second ajax tab, and search again.</li>
<li>N.B. Chrome / IE give a state error, Firefox does not</li>
</ul>
</p>
</div>
<iframe id="tabs-2" src="ajaxTab.aspx" style="width:100%;" ></iframe>
</div>
Also, I'm not sure but this seems like error in the Web_UserControls_search control. In my opinion, NavBarSearchItemNoSearchItem_OnClick method must be refactored as below:
protected void NavBarSearchItemNoSearchItem_OnClick(object sender, EventArgs e)
{
var searchFieldTbx = NavBarSearchItemNo;
var navBarSearchCatHiddenField = NavBarSearchCatHiddenField;
var term = searchFieldTbx != null ? searchFieldTbx.Text : "";
if (term.Length > 0) //There is actually something in the input box we can work with
{
//Response.Redirect(Url.GetUrl("SearchResults", term));
Response.Redirect(ResolveClientUrl("~/Web/SearchResults.aspx?term=" + term + "&cat=" + navBarSearchCatHiddenField.Value));
}
}
Draw attention that we resolving client url when redirecting to search results page and instead of navBarSearchCatHiddenField use navBarSearchCatHiddenField.Value as cat parameter.
I guess that you use AJAX to fill the content of the tab. So in this case, content of your tab will be replaced by the new one from ajax and certainly _VIEWSTATE will be replaced. At server, do you use data from ViewState? In the "static tabs", you should prevent them auto reload by using cache:true
Your issue is that with your ajax call you bring in a complete ASPX page. Including the Form tag and its Viewstate. If you remove the Form tag from ajaxTab.aspx you will see everything works fine. asp.net does not know how to handle two Form tags in one page. Same goes for hidden Viewstate fields. You cannot bring in a full aspx page via ajax. Just bring in the content Div you want to display and you`ll be good to go.

How can I find and scrape by Class using WatiN?

I am using WatiN and trying to scrape an image URL from a weblink, based on the fields class. Viewing the sites code the images info displays as this:
//images code
<div class="doc-banner-icon">
<img src="https://website.com/image.jpg">
</div>
//text code
<div id="doc-original-text">
Once upon a time, in a land far far away...
</div>
What I want to do is use a WatiN call to find that img link. I thought I could use something like the Find.ByClass() call to find specifically that area of the code, but I can't seem to figure out how to get the line of text contained within that class. When I use the Find.ById() on a different field and sent to string it pulls the text content of that area. Below is what I am trying.
using (myIE)
{
//loads the website
myIE.GoTo(txtbxWeblink.Text);
string infoText = myIE.Div(Find.ByClass("doc-banner-icon")).ToString();
//This will successfully return the text fields text.
string imageText = myIE.Div(Find.ById("doc-original-text")).ToString();
}
EDIT - It appears that I may need to use a different call on myIE, there is also myIE.Image, myIE.Link etc, I don't know much about this all still so not sure if Div is the right call here.
Try this...
string infoText = myIE.Div(Find.ByClass("doc-banner-icon")).Images.First().Src;
string imageText = myIE.Div(Find.ById("doc-original-text")).Text;

Sending POST request to page with multiple forms

I have found this great class for sending POST request to a webpage. Now I tried it on a test page with single form and it works. But now I would like to do a POST request to a page, that has multiple forms on the same page. Is it possible to select specific form, if it is defined with name?
For example, like this:
<form method="post" action="index.php" target="_parent">
...
</form>
<form method="post" action="index.php" name="login" target="_top" class="login">
// This is the form that I want to post data
...
<input value="Go" type="submit" id="input_go" />
</form>
EDIT:
This solution provided by Anfurny does not work:
post.PostItems.Add("login", "input_go");
I have updated code, the button that submits has only id defined.
EDIT2:
I have found a good example of a page with two forms. phpMyAdmin demo, it has two forms, one is for selecting different language, the other is for login. This demo has:
username = root
password is empty
Now I have tried to login programmatically with this code (it uses class that I have posted the link on start of the page):
// First we create an instance of a class PostSubmitter.
PostSubmitter post = new PostSubmitter();
// We set the URL to which the POST should go.
post.Url = "http://demo.phpmyadmin.net/STABLE/index.php";
// We add items (password and username).
post.PostItems.Add("pma_username", "root");
post.PostItems.Add("pma_password", "");
// Also tried to add to which login form should post and the
// value set to id of the submit button, no luck.
//post.PostItems.Add("login_form", "input_go");
// Here we set the method.
post.Type = PostSubmitter.PostTypeEnum.Post;
// Getting back the result.
string result = post.Post();
// Writting it to the file.
TextWriter tw = new StreamWriter("C:/response.txt");
tw.WriteLine(result);
tw.Close();
The response.txt file has the same content as the login page, where it should have the code of the welcome page. Now how can I change code, to successfully login?
Usually when you have multiple forms posting to the same place, that you would differentiate them with the button that was clicked. Can you not do the same and add a virtual button (action) to your post list of values?
Have you tried doing something like this:
post.PostItems.Add("FORM_NAME","SUBMIT_BUTTON_NAME ");
?
Where FORM_NAME is the name of the form you wish to submit, and SUBMIT_BUTTON_NAME is the name of the submit button you wish to pretend was pressed (if more than one is present).

Highlight selected text and save it

I am interested in saving text when user selects any text anywhere on a web page that text has to be highlighted and has to save that text as a string in C#.
when same user saw same page next time text has to be highlighted as done previously by him.
If anyone knows a simple elegant way to do this I would really appreciate it, but I'll take any solution at this point. Even if you can point me in the right directions that would be appreciated.
Thanks in advance.
You need to write service WCF or Webservice in server side that will receive userId and text and save it into database.
[WebMethod(Description = "Save Text")]
public string Savetext(int userId ,string text)
{
}
Second method will retrive the text from daatabase by user id
[[WebMethod(Description = "Get text")]
public string GetText(int userId)
{}
In client side do invokation using Ajax calls (Jquery)
Use this to get selected text from page: http://mark.koli.ch/2009/09/use-javascript-and-jquery-to-get-user-selected-text.html
Then in mouseup event copy it to some HiddenField. Now you need a button or maybe AJAX call in mouseup so you can send it to server. On the server side save it to DB along with UserID and page address or ID.
On the next visit of this user to this page check in DB for entry. If it exist put the text in some hidden field. Then using jQuery get that text clientside, find it on page (using regex or something) and select it. You should remember to disregard any HTML markup while finding the text which can be tricky...
That is general way I would take to do this.
you can do that by capturing the selected text and send it via ajax call to your database.
check this example to know haw you can capture the selected text.
If you use jquerythen you will use select() function to capture the selected text
<textarea id="txt"></textarea>
<script>
$(document).ready(function(){
$('textarea').select(function()
{
var selectedText=window.getSelection();
//here put the ajax call to your webservice
});
});
</script>

How do I HTTP POST from an ASP.NET button?

Sorry, another super basic ASP.NET question. this so embarrassing.
I am reading the article on How to: Pass values between ASP.NET pages
In the second approach, they suggest hooking up a button and directing the user to another page using POST. I don't know how to do this. How do I HTTP POST?
"When the source page uses the HTTP POST action to navigate to the target page, you can retrieve posted values from the Form collection in the target page."
This is how I am sending the user to the new page:
protected void btnSubmitForPost_Click(object sender, EventArgs e)
{
Response.Redirect("GetViaPost.aspx");
}
EDIT
The final solution:
You can use ASP.NET webforms. Do the following: On the first page, create your controls and a button that sends the user to a new page. Handle the click event from this button. As stated below, use Server.Transfer with endResponse=false, instead of Response.Redirect(). When you use Response.Redirect, your post data is cleared out. I did not need to specify action in the form or anything else.
In ASP.NET when you click a button, you're posting the entire page's fields by default (as it's contained within a gigantic <form /> tag last time I checked. You can access these values after clicking the button like this:
string MyPostedValue = Request.Form["MyFormField"];
*Edit as per your update in your question, change Response.Redirect() to Server.Transfer() like this:
protected void btnSubmitForPost_Click(object sender, EventArgs e)
{
Server.Transfer("GetViaPost.aspx", true);
}
Then in your GetViaPost.aspx's page you can get any form/query string variable you passed from your sending page like this:
string MyPostedValue = Request.Form["MyFormField"];
If I'm reading this right, all of these answers are missing the question...
You're looking at posting from one Asp.Net form to another, and one of the methods is what you want to figure out - doing a normal http post. The book or article probably is already telling you about the Server.Transfer as another option if I'm guessing right.
If I'm getting the question right, then the simplest answer is to not use a standard ASP.Net form (with the runat = server attribute) as the starting point, but to use a simple standard html form to post to an asp.net page
<form action = "targetpage.aspx" method="post">
...some form fields here
<input type = "submit">
</form>
If in the codebehind you wire up to the button click event, then click the button. It's a POSTback that happens.
Any controls that you have runat="server" will be accessible by their id (and any values set on them) in the codebehind.
In terms of posting data to other pages, you have a number of options available to you.
The querystring, sessions, cookies and viewstate.
A basic example (with no error handling) given your updated Response.Redirect might be:
int someId = int.Parse(txtBoxOnThePage.Text);
Response.Redirect(string.Format("GetViaPost.aspx?myId={0}", someId));
Then on the GetViaPost page you could pull that out by:
HttpContext.Current.Request.QueryString["myId"]
http://www.asp.net/learn/ is a surprisingly good source of information and tutorials for this kind of learning.
ASP.NET buttons always perform a POST. You can set which page the button posts to using the PostBackUrl property of the button. If you leave this blank, the button will post back to the same page that is resides on.
Check out this article for more information.

Categories

Resources