Can we detect when google bot crawl my page ASP.Net - asp.net

i need to programmatically detect when Google bot or any other search engine bot crawl our web site page. i have logic in Application_BeginRequest of my global.asax that when any page is requested then i try to read two cookies value and if anyone is missing then i redirect user to a specific page from where user select country and from there few cookies are dropped in user pc.
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string strCountryCookie = BBAreman.CountryCookie.GetCookieValue();
string strShippingCookie = BBAreman.CountryCookie.GetShippingCookieValue();
if (Request.Url.ToString().IndexOf(".asmx") == -1)
{
if (strCountryCookie.Trim() == "" || strShippingCookie.Trim() == "")
{
if (Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/index.aspx?ShowCountry=true" != HttpContext.Current.Request.Url.ToString())
{
Response.Redirect("~/index.aspx?ShowCountry=true");
}
}
}
}
now when Google bot access any of our page then bot is redirecting to a specific page and not being able to access any of page. as a result our web site is loosing ranking.
i never face this situation.so guys please guide me how to handle this situation. thanks
EDIT
i got a routine like
If(Request.Browser.Crawler) Then
'this is a web bot
Else
'this is a regular user
End If
i guess the above way i can detect that bot is crawling my page or any human? just tell me am i on right track or not ?
Solved
i solved it this way
public class Utility
{
public static bool IsCrawlByBot()
{
List<string> Crawlers = new List<string>()
{
"googlebot","bingbot","yandexbot","ahrefsbot","msnbot","linkedinbot","exabot","compspybot",
"yesupbot","paperlibot","tweetmemebot","semrushbot","gigabot","voilabot","adsbot-google",
"botlink","alkalinebot","araybot","undrip bot","borg-bot","boxseabot","yodaobot","admedia bot",
"ezooms.bot","confuzzledbot","coolbot","internet cruiser robot","yolinkbot","diibot","musobot",
"dragonbot","elfinbot","wikiobot","twitterbot","contextad bot","hambot","iajabot","news bot",
"irobot","socialradarbot","ko_yappo_robot","skimbot","psbot","rixbot","seznambot","careerbot",
"simbot","solbot","mail.ru_bot","spiderbot","blekkobot","bitlybot","techbot","void-bot",
"vwbot_k","diffbot","friendfeedbot","archive.org_bot","woriobot","crystalsemanticsbot","wepbot",
"spbot","tweetedtimes bot","mj12bot","who.is bot","psbot","robot","jbot","bbot","bot"
};
string ua = HttpContext.Current.Request.UserAgent.ToLower();
bool iscrawler = Crawlers.Exists(x => ua.Contains(x));
return iscrawler;
}
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
//if (!Request.Browser.Crawler)
if (!Utility.IsCrawlByBot())
{
string strCountryCookie = BBAreman.CountryCookie.GetCookieValue();
string strShippingCookie = BBAreman.CountryCookie.GetShippingCookieValue();
if (Request.Url.ToString().IndexOf(".asmx") == -1)
{
if (strCountryCookie.Trim() == "" || strShippingCookie.Trim() == "")
{
if (Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/index.aspx?ShowCountry=true" != HttpContext.Current.Request.Url.ToString())
{
Response.Redirect("~/index.aspx?ShowCountry=true");
}
}
}
}
}

Related

Unable to get the values from EditText fields in android

I have facebook integration done for my android app, now I have the FB login button also user can register for our application and login using his email id.
so I have 2 different ways to login.
Problem is that I m unable to get the values in the EditText field provided by user to login.
I m able to get the value in registeration page but not in the login page.
But if I remove all the codes used for FB integration it works fine..
I have a fragment activity.
Please help and let me know if any info needed..
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
try {
Log.i("TAG", "Inside Hash Key");
PackageInfo info = getPackageManager().getPackageInfo("com.package", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash :", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (PackageManager.NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
mainFragment = new MainFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, mainFragment).commit();
} else {
// Or set the fragment from restored state info
mainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(android.R.id.content);
}
try {
Log.i("TAG", "Inside Hash Key");
PackageInfo info = getPackageManager().getPackageInfo("com.package", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash :", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (PackageManager.NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
This is what I have in my oncreate.

ASP.Net and Parallel.Foreach causes buttons to stop working?

i have a very large database of images from the web which i am categorizing (downloaded locally).
so i have a website (locally) to do this, but the db queries were taking long, so i got an idea to "preload" the next page, so that only the very first load of the page would be slow. I save the list of items loaded in a seperate thread in session. So far so good.
I wanted to optimize further, and did some testing on what took the longest, and loading the images to check the size to see if i needed to scale them (set image height and width on the img obj) - so i wanted to do this with a parallel.foreach loop - but after doing this, my buttons on the page stopped responding? i can see the page runs through the page_load event when i press a button, but it doesn't reach the buttons "code":
protected virtual void btnSaveFollowPosts_Click(object sender, EventArgs e)
{...}
any take on what i am doing wrong? i have tried to limit the degree of paralellelism to 1 just to see if that would fix it - but it did not.
Update - code:
trying to boil it down:
protected void Page_Load(object sender, EventArgs e)
{
Search(false);
}
protected void Search(bool updateCounters)
{
if (Session[SessionItems] == null)
{
if (Session[SessionItemsCache] == null)
{
//if is being constructed, wait, else construct
//if construction is not running
if (Session[SessionCacheConstructionRunning] == null)
{
StartPreLoadContent();
}
while (Session[SessionCacheConstructionRunning] != null)
{
Thread.Sleep(25); //block main thread untill items ready
}
}
List<ContentView> contentViewList = Session[SessionItemsCache] as List<ContentView>;
Session[SessionItemsCache] = null; //clean preload cache
Session[SessionItems] = contentViewList; //save in current usage storage
Filltable(ref tblContent, contentViewList);
//preload next batch
StartPreLoadContent();
}
else
{
List<ContentView> contentViewList = Session[SessionItems] as List<ContentView>; //get items from session
Session[SessionItems] = contentViewList; //save in current usage storage
Filltable(ref tblContent, contentViewList);
}
}
protected void StartPreLoadContent()
{
Session[SessionCacheConstructionRunning] = true;
//start task
Thread obj = new Thread(new ThreadStart(RunPreLoadContent));
obj.IsBackground = true;
obj.Start();
}
protected void RunPreLoadContent()
{
using (DBEntities entities = new DBEntities())
{
entities.CommandTimeout = 86400;
IQueryable<ContentView> query = entities.ContentView.Where(some criterias);
List<ContentView> contentViewListCache = query.ToList();
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 7;
Parallel.ForEach(contentViewListCache, options, content =>
{
try
{
Interlocked.Increment(ref imageSizeCount);
string path = Path.Combine(basePath, content.LocalPath);
int imageSize = 150;
using (System.Drawing.Image realImage = System.Drawing.Image.FromFile(path))
{
double scale = 0;
if (realImage.Height > realImage.Width)
{
scale = (double)realImage.Height / imageSize;
}
else
{
scale = (double)realImage.Width / imageSize;
}
if (scale > 1)
{
content.ImageHeight = (int)((double)realImage.Height / scale);
content.ImageWidth = (int)((double)realImage.Width / scale);
content.ImageScaled = true;
}
content.ShowImage = true;
}
}
catch (Exception)
{
}
});
Session[SessionItemsCache] = contentViewListCache;
Session[SessionCacheConstructionRunning] = null; //cache ready
}
protected virtual void btnSave_Click(object sender, EventArgs e)
{
try
{
//save
...some reading and saving going on here...
//update
Session[SessionItems] = null;
Search(true);
}
catch (Exception error)
{
ShowError(error);
}
}
I agree with a previous comment: you should probably do this logic earlier in the page lifecycle. Consider overriding OnInit and putting it there.
Also, you could try this line of code instead of your current thread code (which is more suited to Windows not Web programming):
using System.Threading.Tasks;
Task.Run(() => { RunPreLoadContent(); });

How to show the details of the logged in user without the Request.QueryString[" "]; method in asp.net?

I need to do is this:
Each user, when they log in, can see their details. For that, I have created a form called Shiko.aspx.
The code behind this form is:
public partial class Shiko : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string idCard = Request.QueryString["id"];
if (!String.IsNullOrEmpty(idCard))
{
Employee.DetailsDataTable table = Matrix.GetEmployeeById(idCard);
if (table.Rows.Count > 0)
{
System.Data.DataRow row = table.Rows[0];`
lblIdCard.Text = row["IdCard"].ToString();
lblPassword.Text = row["Password"].ToString();
lblEmri.Text = row["Firstname"].ToString();
lblMbiemri.Text = row["Lastname"].ToString();
lblGjinia.Text = row["Gender"].ToString();
lblDitelindja.Text = row["Birthday"].ToString();
lblPaga.Text = row["Salary"].ToString();
lblTelefoni.Text = row["Phone"].ToString();
lblQyteti.Text = row["City"].ToString();
}
else
{
// HERE IS THE PART OF THE CODE I NEED TO ADD
}
}
}
}
The problem is that when the admin logs in and clicks on the Details link on his panel, using the QueryString it lets him see the details of that employer, but if he clicks on the NavigationMenu "Details" without using the query string it shows only an empty form with the names of each row ( I used labels in the form) but it doesn't populate the form with the details of the logged in user.
My question is, how to do that?

Count the no of Visitors

I have stored resumes in my database and i have retrive it from asp.net web page by creating linkbutton...i can view ,download the resumes which i stored in my database.My issuse is when i view one resume example (domnic resume)then no of visitor for domnic resume should be count .if again i view that resume no of visitor should be 2...how can i do that in asp.net?
There are a ton of ways to do this, each have their quirks. Here is a quick and dirty way to do it, the only thing to remember is that the Session_OnEnd can be a bit flaky.
public void Application_OnStart(Object sender, EventArgs e)
{
Hashtable ht = (Hashtable)Application["SESSION_LIST"];
if(ht == null)
{
ht = new Hashtable();
lock(Application)
{
Application["SESSION_LIST"] = ht;
Application["TOTAL_SESSIONS"] = 0;
}
}
}
public void Session_OnStart(Object sender, EventArgs e)
{
Hashtable ht = (Hashtable)Application["SESSION_LIST"];
if(ht.ContainsKey(Session.SessionID) == false)
{
ht.Add(Session.SessionID, Session);
}
lock(Application)
{
int i = (int)Application["TOTAL_SESSIONS"];
i++;
Application["TOTAL_SESSIONS"] = i;
}
}
public void Session_OnEnd(Object sender, EventArgs e)
{
Session.Clear();
Hashtable ht = (Hashtable)Application["SESSION_LIST"];
ht.Remove(Session.SessionID);
lock(Application)
{
int i = (int)Application["TOTAL_SESSIONS"];
i--;
Application["TOTAL_SESSIONS"] = i;
}
}
Here's another way...
Membership.GetNumberOfUsersOnline();
You can keep track of no of views displayed by keeping the count in the database or a persistent storage of your choice. Whenever a particular resume view is requested, update the view count for that resume. You may disclose some elements of the design you have done to get more specific answers.
If you just want to see this count as a developer/admin, and you have interest in collecting stats site-wide, you may also look into using Google Analytics.

ASP:TextBox Value disappears in postback only when password

I have an asp.net textbox like this:
<asp:TextBox ID="PINPad" runat="server" Columns="6" MaxLength="4"
CssClass="PINTextClass"></asp:TextBox>
It is, as you might have guessed, the text box from an on screen PIN pad. Javascript fills in the values. The page is posted back every five seconds (using an update panel if that matters) to update various other unrelated items on the screen. This works just fine.
However, when I convert it to a password text box, like this:
<asp:TextBox ID="PINPad" runat="server" Columns="6" MaxLength="4"
CssClass="PINTextClass" TextMode="Password"></asp:TextBox>
Then whenever the page posts back, the text box is cleared out on the screen and the textbox is empty (though during the timer event, the value does make it back to the server.)
Any suggestions how to fix this, so that it retains its value during postback?
As a security feature, ASP.NET tries to disallow you from sending the password value back to the client. If you're okay with the security issues (i.e. it's either not really secure information or you're sure that the connection is secure), you can manually set the "value" attribute of the control, rather than using its Text property. It might look something like this:
this.PINPad.Attributes.Add("value", this.PINPad.Text);
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (!(String.IsNullOrEmpty(txtPwd.Text.Trim())))
{
txtPwd.Attributes["value"]= txtPwd.Text;
}
if (!(String.IsNullOrEmpty(txtConfirmPwd.Text.Trim())))
{
txtConfirmPwd.Attributes["value"] = txtConfirmPwd.Text;
}
}
}
here is another way to do it:-
using System;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary
{
public class PWDTextBox : TextBox
{
public PWDTextBox()
{
this.TextMode = TextBoxMode.Password;
}
public string Password
{
get
{
string val = (string)ViewState["pwd"];
if (string.IsNullOrEmpty(val))
{
return "";
}
else
{
return val;
}
}
set
{
ViewState["pwd"] = value;
}
}
public override string Text
{
get
{
return Password;
}
set
{
Password = value;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.Text = Password;
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Password);
}
}
}
The problem of losing the password in the postback can be avoid making use of Asynchronous JavaScript calls, lets describe a typical scenario for a Login page:
Lets say we have a Login page which allows the user to change the language of its labels when the user choose a language with a dropdownlist
a solution would be to invoke selectedIndexChanged event of the dropdownlist, make a postback which goes to the server and picks up the labels in the chosen language.
in this scenario the field password will be lost due to the security feature of ASP.NET which makes passwords fields not persisted between a postbacks.
This scenario can be solved if the postback is avoided making use of Asynchronous JavaScript Technology and XML (Ajax) calls.
Add a javascript function which will be invoked from the dropdownlist control, in this case this function is assigned to the Command property of the dropdownlist in code behind:
function ValueChanged(div)
{
var table = div.getElementsByTagName("table");
if (table && table.length > 0)
{
var t = table[0].getAttribute('type');
if (t != null && (t == "DropDown"))
{
var inputs = div.getElementsByTagName("input");
if (inputs && inputs.length == 2)
{
{
Translate(inputs[1].value);
}
}
}
}
}
The Translate function takes as parameter the selected option language in the dropdown control and performs the asynchronous call as shown bellow.
function Translate(lang)
{
var request = null;
if (window.XMLHttpRequest)
{
request = new XMLHttpRequest();
if (request.overrideMimeType)
{
request.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject)
{
request = new ActiveXObject("Msxml2.XMLHTTP");
}
if (request == null)
{
return;
}
var url = "GetLoginTranslations.aspx";
request.open('GET', url +'?lang=' + lang, true);
request.setRequestHeader("Cache-Control", "no-cache");
request.setRequestHeader("Pragma", "no-cache");
request.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
request.onreadystatechange = function () { TranslateLabels(request); };
request.send(null);
}
the function Translate shown above performs the call and get the results in the specified .aspx page (in this case "GetLoginTranslations.aspx")
when the request is completed and the request.onreadystatechange is set to the function TranslateLabels this function will be executed.
on this way the postback is not executed as before in the event onSelectedIndexChanged of the dropdownlist control.
the TranslateLabels function would look something like :
function TranslateLabels(request)
{
if (request.readyState == 4)
{
if (request.status == 200)
{
if (request.responseXML)
{
var objRoot = request.responseXML.documentElement;
if (objRoot)
{
if (objRoot.nodeName == "strings")
{
for (var i = 0; i < objRoot.childNodes.length; i++)
{
var node = objRoot.childNodes[i];
var elem;
switch (node.getAttribute("id"))
{
case "lbl_login":
elem = document.getElementById("lbl_login");
if (elem)
elem.innerHTML = node.firstChild.nodeValue;
break;
}
///....
}
}
}
}
}
}
the request.responseXML contains the XML built in the page GetLoginTranslations.aspx and the structure of this XML is defined there.
the Page_Load() event in the GetLoginTranslations.aspx should look like:
protected void Page_Load(object sender, EventArgs e)
{
if (Request["lang"] != null)
strLang = Request["lang"];
//init response
Response.Clear();
Response.Cache.SetExpires(DateTime.Now);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetValidUntilExpires(true);
Response.ContentType = "application/xml";
Response.Charset = "utf-8";
XmlTextWriter xml = new XmlTextWriter(Response.OutputStream, System.Text.Encoding.UTF8)
{
Formatting = Formatting.None
};
xml.WriteStartDocument();
xml.WriteStartElement("strings");
xml.WriteStartElement("string");
xml.WriteAttributeString("id", "lbl_login");
xml.WriteString(GetTranslation("label_login", strLang));
xml.WriteEndElement();
// ... the other labels
xml.WriteEndElement(); //</strings>
xml.Close();
}
Some other considerations:
set the the property AutoPostback of the dropdownlist to false.
Happens both for view-model properties named 'Password' and 'PIN'. You can bypass the behavior by defining those as:
string Password ;
... rather than:
string Password { get; set; }
If you do so, features such the 'LabelFor' macro displaying 'DisplayAttribute.Name' no longer works, so you'd have to define those directly in the HTML.
Or you can simply name the fields something other than 'Password' or 'PIN'.

Resources