Basically I have a webform with a scriptmanager and a button to update the results returned from the class webspider (web spider that searches for broken links for a given url). I am trying to convert the code to mvc and have achieved most of this except for the code that is highlighted in bold as I do not have a scriptmanager in the mvc view, can some please give me some pointers on how I can do this, many thanks. -
default.aspx -
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="_check404._Default" %>
<asp:Content runat="server" ID="FeaturedContent" ContentPlaceHolderID="FeaturedContent">
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1><%: Title %>.</h1>
<h2>Modify this template to jump-start your ASP.NET application.</h2>
</hgroup>
<p>
To learn more about ASP.NET, visit http://asp.net.
The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET.
If you have any questions about ASP.NET visit
our forums.
</p>
</div>
</section>
</asp:Content>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<h3>Search results:</h3>
<asp:Label ID="lblTot" runat="server" />
<asp:Label runat="server" ID="lblStatus" />
<asp:UpdatePanel runat="server" ID="pnlLinks">
<ContentTemplate> -->
<asp:GridView runat="server" ID="grvLinks" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="NavigateUrl" HeaderText="Url" />
<asp:ButtonField DataTextField="Status" HeaderText="Status" />
</Columns>
</asp:GridView>
<asp:Button runat="server" ID="btnUpdateResults" Text="Update Results" />
</ContentTemplate>
</asp:UpdatePanel>
default.aspx.cs -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using _check404.Spider;
using System.Net;
namespace _check404
{
public partial class _Default : Page
{
private string script = #"setTimeout(""__doPostBack('{0}','')"", 5000);";
private WebSpider WebSpider
{
get { return (WebSpider)(Session["webSpider"] ?? (Session["webSpider"] = new WebSpider())); }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!this.WebSpider.IsRunning)
{
string url = "http://bbc.co.uk";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
this.WebSpider.Execute(url);
lblTot.Text = WebSpider.Tot.ToString();
}
//////////////////////////the following code is what I am trying to convert
if (this.WebSpider.IsRunning)
{
this.lblStatus.Text = "Processing...";
ScriptManager.RegisterStartupScript(this, this.GetType(),
this.GetType().Name, string.Format(script, this.btnUpdateResults.ClientID), true);
}
///////////////////////////////////////////////////////////////////////////////////////
this.grvLinks.DataSource = this.WebSpider.Links;
this.grvLinks.DataBind();
}
}
}
spider.cs -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
namespace _check404.Spider
{
public class WebSpider
{
public int Tot { get; set; }
const int LIMIT = 10;
string[] invalidTypes = { ".zip", ".doc", ".css", ".pdf", ".xls", ".txt", ".js", ".ico" };
public List<Link> Links;
public bool IsRunning { get; set; }
public WebSpider()
{
this.Links = new List<Link>();
}
public void Execute(string url)
{
this.Links.Clear();
this.Links.Add(new Link() { Status = HttpStatusCode.OK, NavigateUrl = url });
this.IsRunning = true;
WaitCallback item = delegate(object state) { this.FindLinks((UrlState)state); };
ThreadPool.QueueUserWorkItem(item, new UrlState() { Url = url, Level = 0 });
Tot = Links.Count();
}
public void FindLinks(UrlState state)
{
try
{
string html = new WebClient().DownloadString(state.Url);
MatchCollection matches = Regex.Matches(html, "href[ ]*=[ ]*['|\"][^\"'\r\n]*['|\"]");
foreach (Match match in matches)
{
string value = match.Value;
value = Regex.Replace(value, "(href[ ]*=[ ]*')|(href[ ]*=[ ]*\")", string.Empty);
if (value.EndsWith("\"") || value.EndsWith("'"))
value = value.Remove(value.Length - 1, 1);
if (!Regex.Match(value, #"\((.*)\)").Success)
{
if (!value.Contains("http:"))
{
Uri baseUri = new Uri(state.Url);
Uri absoluteUri = new Uri(baseUri, value);
value = absoluteUri.ToString();
}
if (this.Links.Exists(x => x.NavigateUrl.Equals(value))) continue;
try
{
bool validLink = true;
foreach (string invalidType in invalidTypes)
{
string v = value.ToLower();
if (v.EndsWith(invalidType) || v.Contains(string.Format("{0}?", invalidType)))
{
validLink = false;
break;
}
}
if (validLink)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(value);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
this.Links.Add(new Link() { Status = response.StatusCode, NavigateUrl = value });
if (response.StatusCode == HttpStatusCode.OK && state.Level < LIMIT)
{
WaitCallback item = delegate(object s) { FindLinks((UrlState)s); };
ThreadPool.QueueUserWorkItem(
item, new UrlState() { Url = value, Level = state.Level + 1 });
}
}
}
catch
{
this.Links.Add(new Link()
{
Status = HttpStatusCode.ExpectationFailed,
NavigateUrl = value
});
}
}
}
}
catch
{
///
/// If downloading times out, just ignore...
///
}
}
}
}
It looks like you are trying to automatically click a button after 5 seconds if the your spider job is running.
All the script manager is doing is embedding a tag containing your javascript when the markup is generated.
Id say the easiest way to do this is to add an attribute to your model.
class MyModel
{
public bool SpiderRunning { get; set; }
}
Then set this in your controller:
model.SpiderRunning = this.WebSpider.IsRunning
Then in your view, only add the script to the page if this value is true:
#if(Model.SpiderRunning)
{
<script>setTimeout(function(){document.getElementById("btnUpdateResults").click();}, 5000);</script>
}
Related
This is my ASP.NET form. I want to add invisible recaptcha to it with server side validation. Can someone please help?
I can do client side validation but it doesnt use secret key. My another questions is Do we need secret key for invisible recaptcha?
Please see serverside code that i used for google recaptcha but it is not working for Invisible recaptcha. I am getting this error : -
reCAPTCHA Error: missing-input-response: Not Valid Recaptcha
<div id="ContactFormDiv" runat="server">
<div class="form-row form-required">
<asp:Label ID="YourNameLabel" runat="server" AssociatedControlID="YourNameTextBox"> Your Name:</asp:Label>
<asp:TextBox ID="YourNameTextBox" runat="server" CssClass="form300" MaxLength="150"></asp:TextBox>
</div>
<div class="form-row form-required">
<div id='recaptcha' class="g-recaptcha"
data-sitekey="site key"
data-callback="onSubmit"
data-size="invisible">
</div>
</div>
<div class="form-row-buttons">
<asp:Button ID="SendMessageButton" ClientIDMode="Static" runat="server" Text="Send Message" CssClass="buttonPositive"
CausesValidation="True" OnClick="SendMessageButton_Click" />
</div>
</div>
Javascript Code
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js" async defer></script>
Serverside Code
public class MyObject
{
public string success { get; set; }
}
public static string ReCaptcha_Key = "------------------Site Key-----------------";
public static string ReCaptcha_Secret = "--------------Secret Key ---------------";
public bool ValidateReCaptcha()
{
bool Valid = false;
//start building recaptch api call
var sb = new StringBuilder();
//Getting Response String Append to Post Method
string Response = Request["g-recaptcha-response"];
string url = "https://www.google.com/recaptcha/api/siteverify?secret=" + ReCaptcha_Secret + "&response=" + Response;
sb.Append(url);
//make the api call and determine validity
using (var client = new WebClient())
{
var uri = sb.ToString();
var json = client.DownloadString(uri);
var serializer = new DataContractJsonSerializer(typeof(RecaptchaApiResponse));
var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
var result = serializer.ReadObject(ms) as RecaptchaApiResponse;
//--- Check if we are able to call api or not.
if (result == null)
{
lblmsg.Text = "Captcha was unable to make the api call";
}
else // If Yes
{
//api call contains errors
if (result.ErrorCodes != null)
{
if (result.ErrorCodes.Count > 0)
{
foreach (var error in result.ErrorCodes)
{
lblmsg.Text = "reCAPTCHA Error: " + error;
}
}
}
else //api does not contain errors
{
if (!result.Success) //captcha was unsuccessful for some reason
{
lblmsg.Text = "Captcha did not pass, please try again.";
}
else //---- If successfully verified. Do your rest of logic.
{
lblmsg.Text = "Captcha cleared ";
Valid = true;
}
}
}
}
return Valid;
}
public bool temp = true;
protected void SendMessageButton_Click(object sender, EventArgs e)
{
temp = ValidateReCaptcha();
if (temp == false)
{
lblmsg.Text = "Not Valid Recaptcha";
lblmsg.ForeColor = System.Drawing.Color.Red;
}
else
{
lblmsg.Text = "Successful";
lblmsg.ForeColor = System.Drawing.Color.Green;
}
Page.Validate();
if (this.Page.IsValid == true && temp == true)
{ //Page and invisible recaptcha is valid }
}
I am getting this error : -
reCAPTCHA Error: missing-input-response: Not Valid Recaptcha
This is how I implemented the working sample:
-- Client Side (Refer to Google Documentation )
<head>
<!-- Google Invisible Captcha -->
<script src='https://www.google.com/recaptcha/api.js'/>
<script>
function onSubmit(token) {
document.getElementById("htmlForm").submit();
}
</script>
</head>
<body>
<form id="htmlForm" action="Default.aspx" method="post">
<input name="txtName" />
<input name="txtEmailAddress" />
<button class="g-recaptcha btn btn-default"
data-sitekey="-------------------Site key--------------"
data-callback="onSubmit">
Submit Request
</button>
</form>
</body>
-- Server Side (keeps secret Key)
public static bool IsValidCaptcha()
{
var secret = "--------------Secret Key ---------------";
var req =
(HttpWebRequest)
WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=" + secret + "&response=" + HttpContext.Current.Request.Form["g-recaptcha-response"]);
using (var wResponse = req.GetResponse())
{
using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
{
string responseFromServer = readStream.ReadToEnd();
if (!responseFromServer.Contains("\"success\": false"))
return true;
}
}
return false;
}
I also have similar problem and it looks like it is harder to find any decent example. However, I saw that you have set
data-callback="onSubmit"
but I didn't see where you have defined that method. Is it there? Could that be what are you missing?
I have an issue where I am setting session variables using the master page, then using those session variables to deal with content in my placeholder. However, the session variables are not showing as updated in the content. I've made a small example below.
I need the session variables to be updated in both the masterpage and the content. Right now, it's as if the content codebehind is running either before or simultaneous with the masterpage. I assumed that the masterpage codebehind would run first, thus setting the session variables. Any help would be greatly appreciated. Thanks! (.NET 2.0 build using C#)
testmass.master
<%# Master Language="C#" inherits="gpworklist.testmass"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head runat="server">
</head>
<body>
<form id="testthisform">
<select id="test1sel" name="test1" runat="server"></select>
<select id="test2sel" name="test2" runat="server"></select>
<input type="submit" value="Submit" />
</form>
<div id="testsess" runat="server"></div>
<asp:ContentPlaceHolder id="cntnt_phldr" runat="server">
</asp:ContentPlaceHolder>
</body>
</html>
testmass.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Web.UI.WebControls;
namespace gpworklist
{
public class testmass: MasterPage
{
public string defProv;
public testmass()
{
}
public void Page_Load()
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.MinValue);
HtmlSelect sel1 = (HtmlSelect)this.FindControl("ctl00$test1sel");
HtmlSelect sel2 = (HtmlSelect)this.FindControl("ctl00$test2sel");
HtmlGenericControl div = (HtmlGenericControl)this.FindControl("ctl00$testsess");
string def1;
string def2;
ListItem item;
if (Request["ctl00$test1sel"] != null && Request["ctl00$test1sel"] != "")
{
Session["test1"] = Request["ctl00$test1sel"];
}
if (Request["ctl00$test2sel"] != null && Request["ctl00$test2sel"] != "")
{
Session["test2"] = Request["ctl00$test2sel"];
}
if (Session["test1"] != null)
{
def1 = Session["test1"].ToString();
}
else
{
def1 = "";
}
if (Session["test2"] != null)
{
def2 = Session["test2"].ToString();
}
else
{
def2 = "";
}
for (int i = 0; i <= 10; i++)
{
item = new ListItem(i.ToString(), i.ToString());
if (i.ToString() == def1)
{
item.Selected = true;
}
sel1.Items.Add(item);
}
//Session["test1"] = sel1.Value;
for (int i = 0; i <= 10; i++)
{
item = new ListItem(i.ToString(), i.ToString());
if (i.ToString() == def2)
{
item.Selected = true;
}
sel2.Items.Add(item);
}
Session["test2"] = sel2.Value;
div.InnerHtml = Session["test1"] + " - " + Session["test2"];
}
}
}
testpage.aspx
<%# Page Language="C#" MasterPageFile="testmass.master" Inherits="gpworklist.testpage"%>
<asp:content ID="contentstuff" contentplaceholderid="cntnt_phldr" runat="server">
<div id="testpagesess" runat="server"></div>
</asp:content>
testpage.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Web.UI.WebControls;
namespace gpworklist
{
public class testpage: Page
{
public testpage()
{
}
public void Page_Load()
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.MinValue);
HtmlGenericControl div = (HtmlGenericControl)this.FindControl("ctl00$cntnt_phldr$testpagesess");
div.InnerHtml = Session["test1"] + " - " + Session["test2"];
}
}
}
A content page's event does fire before the same master page's event.
see http://msdn.microsoft.com/en-us/library/vstudio/dct97kc3(v=vs.100).aspx
You should use the Init event of the MasterPage, instead of the Load event. That will be called before the Page.Load.
I am trying to write a dashboard with information about the website's hits and where people come from etc.
I wrote the following page:
<%# Page Language="C#" Inherits="Daschboard.Board" MasterPageFile="~/site.master" %>
<asp:Content id="main" runat="server" ContentPlaceHolderID="main">
<asp:UpdatePanel runat="server" id="updateableWidgets">
<ContentTemplate>
<asp:ContentPlaceHolder id="WidgetsTable">
</asp:ContentPlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
With the following code behind:
using Widgets;
using System;
using System.Text;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Configuration;
using MySql.Data.MySqlClient;
namespace Daschboard
{
public partial class Board : System.Web.UI.Page
{
protected List<IWidget> widgets;
private MySqlConnection db = new MySqlConnection (ConfigurationManager.AppSettings ["mySql"]);
protected void Page_Load(object sender, EventArgs e)
{
widgets = new List<IWidget>();
BuildWidgtTable();
var WidgetThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.InitWidgets));
WidgetThread.Start();
}
private string BuildWidgtTable ()
{
StringBuilder sb = new StringBuilder ();
db.Open ();
var tableName = ConfigurationManager.AppSettings ["DatabaseSiteName"];
var query = "SELECT * FROM " + tableName + ", Widget WHERE " + tableName + ".WidgetID = Widget.WidgetID";
var command = new MySqlCommand (query, db);
var result = command.ExecuteReader ();
while (result.Read()) {
widgets.Add(getWidget(result.GetString(4)));
}
db.Close ();
sb.Append("<table>\n");
sb.Append("</table>");
result.Close();
return sb.ToString();
}
private void InitWidgets ()
{
db.Open();
foreach (var widget in widgets) {
var siteId = ConfigurationManager.AppSettings["siteID"];
var query = "SELECT * FROM Values, Widget WHERE Widget.WidgetID = Values.WidgetID AND SiteID = " + siteId;
var command = new MySqlCommand(query, db);
var result = command.ExecuteReader();
while(result.Read()){
Console.WriteLine(result);
}
result.Close();
widget.Init ("1");
}
db.Close();
}
private IWidget getWidget (string fileName)
{
IWidget widget = null;
switch (fileName) {
case "PageHits":
widget = new PageHits();
break;
case "SiteHits":
widget = new SiteHits();
break;
}
return widget;
}
}
}
When I run this something goes wrong; the debugger stops working without a good error.
It does load the widgets from the database but it doesn't get the values from the database.
I am using Monodevelop on a Mac.
You are running the widget initialization method in a separate thread (InitWidgets method). The page might have already finished rendering when this method executes. If you want to use asynchronous operations in ASP.NET I would recommend you reading about Asynchronous Pages on MSDN. The idea is to mark your WebForm as asynchronous by setting Async="true" in your Page directive (<%# Page Async="true" ... %>) and then use the RegisterAsyncTask method on your web form.
How to post something on a facebook page's wall from a asp.net website.
Google search says that I have to create an app to do this. Is it possible to post to facebook wall without creating an app?
not sure where to start. I tried developers.facebook.com and csharpsdk.org. Not much luck. Is there an example? or a tutorial using the graph api?
Creating an APP on facebook is a minimum requirement for FB to accept your posts. What you are asking doesnt make much sense. Imagine if anyone can post stuff to FB, we probably wouldnt be discussing about this here (it would have been dead by now and I am glad it is how it is) I suggest you read these links for a quick start
FB API in general:
http://developers.facebook.com/docs/reference/javascript/FB.api/
C# SDK: http://developers.facebook.com/blog/post/395/
Graph Api: http://developers.facebook.com/docs/reference/api/
Hope this gives some starting points. Good luck
After you create the application stuff in facebook and get your unique application id and secret code use the following (code behind)
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Web.Security;
using System.Xml;
using System.Collections.Specialized;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
readonly static string myurl = "your url";
readonly static string App_ID = "Your application id";
readonly static string App_Secret = "your secret code";
readonly static string scope = "email";
FacebookUser me;
readonly static DataContractJsonSerializer userSerializer = new DataContractJsonSerializer(typeof(FacebookUser));
protected void Page_Load(object sender, EventArgs e)
{
if (Session["code"] == null)
{
fbLogin.Visible = true;
}
else
{
fbLogin.Visible = false;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if ((!IsPostBack) || Session["code"] == null)
{
string code = Request.QueryString["code"];
if (code == null)
{
Session["code"] = null;
}
else
{
Session["code"] = code;
// oAuth = new oAuthFacebook();
//// oAuthFacebook oFB = new oAuthFacebook();
// //Response.Redirect(oFB.AuthorizationLinkGet());
// oAuth.AccessTokenGet(Request["code"]);
// if (oAuth.Token.Length > 0)
// {
// //We now have the credentials, so we can start making API calls
// string url = "https://graph.facebook.com/me/likes?access_token=" + oAuth.Token;
// string json = oAuth.WebRequest(oAuthFacebook.Method.GET, url, String.Empty);
// }
}
string error_description = Request.QueryString["error_description"];
string originalReturnUrl = Request.QueryString["ReturnUrl"]; // asp.net logon param
Uri backHereUri = Request.Url; // modify for dev server
if (!string.IsNullOrEmpty(code)) // user is authenticated
{
me = GetUserDetails(code, backHereUri);
FormsAuthentication.SetAuthCookie(me.email, false); // authorize!
if (!string.IsNullOrEmpty(originalReturnUrl))
Response.Redirect(originalReturnUrl);
}
if (!string.IsNullOrEmpty(error_description)) // user propably disallowed
{
OnError(error_description);
}
fbLogin.Visible = !User.Identity.IsAuthenticated;
if (string.IsNullOrEmpty(code))
{
fbLogin.Visible = true;
LoginName1.Visible = false;
}
else
{
fbLogin.Visible = false;
LoginName1.Visible = true;
LoginName1.Text = "User Email: " + me.email.ToString() + " Name: " + me.first_name.ToString() + " Sname: " + me.last_name.ToString() + " Verified: " + me.verified.ToString();
}
fbLogin.NavigateUrl = string.Format(
CultureInfo.InvariantCulture,
"https://www.facebook.com/dialog/oauth?"
+ "client_id={0}&scope={1}&redirect_uri={2}",
App_ID,
scope,
Uri.EscapeDataString(backHereUri.OriginalString));
}
}
FacebookUser GetUserDetails(string code, Uri backHereUri)
{
Uri getTokenUri = new Uri(
string.Format(
CultureInfo.InvariantCulture,
"https://graph.facebook.com/oauth/access_token?"
+ "client_id={0}&client_secret={1}&code={2}&redirect_uri={3}",
App_ID,
App_Secret,
Uri.EscapeDataString(code),
Uri.EscapeDataString(backHereUri.OriginalString))
);
using (var wc = new WebClient())
{
string token = wc.DownloadString(getTokenUri);
Session["token"] = token;
Uri getMeUri = new Uri(
string.Format(
CultureInfo.InvariantCulture,
"https://graph.facebook.com/me?{0}",
token)
);
using (var ms = new MemoryStream(wc.DownloadData(getMeUri)))
{
var me = (FacebookUser)userSerializer.ReadObject(ms);
return me;
}
}
}
void OnError(string error_description)
{
Controls.Add(new Label()
{
CssClass = "oauth-error",
Text = error_description
}
);
}
[Serializable]
class FacebookUser
{
public long id;
public string name;
public string first_name;
public string last_name;
public string link;
public string email;
public string timezone;
public string locale;
public bool verified;
public string updated_time;
}
protected void Button1_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
WebRequest req = WebRequest.Create("https://api.facebook.com/restserver.php?method=links.getStats&urls=http://localhost:5064/default.aspx,http://www.facebook.com");
WebResponse resp = req.GetResponse();
StreamReader reader = new StreamReader(resp.GetResponseStream());
string xml = reader.ReadToEnd();
xml = xml.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").Replace("links_getStats_response xmlns=\"http://api.facebook.com/1.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd\" list=\"true\"", "links_getStats_response");
doc.LoadXml(xml);
XmlNodeList xnList = doc.SelectNodes("links_getStats_response/link_stat");
foreach (XmlNode xn in xnList)
{
string fullurls = xn["url"].InnerText;
string likes = xn["like_count"].InnerText;
string comment = xn["comment_count"].InnerText;
string normalisedurls = xn["normalized_url"].InnerText;
}
}
public string WebRequests(string method, string url, string postData)
{
HttpWebRequest webRequest = null;
StreamWriter requestWriter = null;
string responseData = "";
webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
webRequest.Method = method.ToString();
webRequest.ServicePoint.Expect100Continue = false;
webRequest.UserAgent = HttpContext.Current.Request.UserAgent;
webRequest.Timeout = 20000;
if (method == "POST")
{
webRequest.ContentType = "application/x-www-form-urlencoded";
//POST the data.
requestWriter = new StreamWriter(webRequest.GetRequestStream());
try
{
requestWriter.Write(postData);
}
catch
{
throw;
}
finally
{
requestWriter.Close();
requestWriter = null;
}
}
responseData = WebResponseGet(webRequest);
webRequest = null;
return responseData;
}
public string WebResponseGet(HttpWebRequest webRequest)
{
StreamReader responseReader = null;
string responseData = "";
try
{
responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
responseData = responseReader.ReadToEnd();
}
catch
{
throw;
}
finally
{
webRequest.GetResponse().GetResponseStream().Close();
responseReader.Close();
responseReader = null;
}
return responseData;
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Session["code"] != null)
{
string urls = "https://graph.facebook.com/me/feed?" + Session["token"];
var json = WebRequests("POST", urls, "message=" + HttpUtility.UrlEncode("" + TextBox1.Text));
}
}
}
}
AND for default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:HyperLink runat="server" Text="Log in with Facebook" id="fbLogin"/><br /><br />
<asp:Label ID="LoginName1" runat="server" Text="" Font-Bold="true"></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Get Likes And Comments" onclick="Button1_Click" />
<br />
<asp:TextBox ID="TextBox1" runat="server" Width="407px" Text="Testing Api by c# code"></asp:TextBox>
<asp:Button ID="Button2" runat="server" Text="Post To me"
onclick="Button2_Click" />
</div>
</form>
</body>
</html>
Hope that helps
I have a UserControl ('AddressInfoGroup') within an updatepanel that dynamically loads user controls ('AddressInfo') via the loadControl method. I have two other such controls on the same page, both of which function correctly.
When the AddressInfoGroup control renders an AddressInfo control to the page, the text boxes in AddressInfo have id's unchanged from the ascx markup. These id's should have been dynamically generated by the .NET clientID process. Because of this, when a second AddressInfo control is added to AddressInfoGroup, I get a runtime exception "An entry with the same key already exists". The two working controls produce proper clientID's and consequently don't return this error.
I should also mention that the AddressInfoGroup control has a few buttons which are correctly rendered with clientID so it seems to be an issue with the AddressInfo control itself. Any suggestions at all would be really helpful!
AddressInfoGroup markup
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddressInfoGroup.ascx.cs" Inherits="MFRI.Controls.Contact.AddressInfoGroup" %>
<h2>Address information</h2>
<div class="formGroup">
<asp:PlaceHolder ID="plc_infoCtrls" runat="server" />
<asp:Button id="btn_addAddress" CssClass="btn_add" Text="v" runat="server" OnClick="addAddress_click" UseSubmitBehavior="false" CausesValidation="false" />
<asp:Button id="btn_removeAddress" CssClass="btn_remove" Text="^" runat="server" OnClick="removeAddress_click" UseSubmitBehavior="false" CausesValidation="false" />
</div>
AddressInfoGroup codebehind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MFRI.Common.Contact;
using MFRI.Common;
namespace MFRI.Controls.Contact
{
public partial class AddressInfoGroup : System.Web.UI.UserControl
{
private int _maxNumberOfControls = 3;
private int _minNumberOfControls = 1;
private List<Address> _controlListToBind = null;
public int NumberOfControls
{
get { return SafeConvert.ToInt(ViewState["NumberOfControls"] ?? 0); }
set { ViewState["NumberOfControls"] = value; }
}
public bool Editable
{
get { return (bool)(ViewState["InfoControlsEditable"] ?? false); }
set { ViewState["InfoControlsEditable"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (_controlListToBind != null && _controlListToBind.Count > 0)
{
NumberOfControls = _controlListToBind.Count;
foreach (Address address in _controlListToBind)
{
AddressInfo addressInfo = (AddressInfo)LoadControl("AddressInfo.ascx");
addressInfo.InitControl(Editable, address);
plc_infoCtrls.Controls.Add(addressInfo);
}
}
else
{
if (NumberOfControls <= 0)
NumberOfControls = 1;
for (int i = 0; i < NumberOfControls; i++)
{
AddressInfo addressInfo = (AddressInfo)LoadControl("AddressInfo.ascx");
addressInfo.InitControl(Editable, null);
plc_infoCtrls.Controls.Add(addressInfo);
}
}
RefreshButtons();
}
public void BindAddressList(List<Address> addressList)
{
_controlListToBind = addressList;
}
public List<Address> GetAddressList()
{
List<Address> returnList = new List<Address>();
foreach (AddressInfo addressInfo in plc_infoCtrls.Controls.OfType<AddressInfo>())
{
returnList.Add(addressInfo.GetAddress());
}
return returnList;
}
private void RefreshButtons()
{
btn_addAddress.Enabled = false;
btn_removeAddress.Enabled = false;
if (Editable)
{
if (NumberOfControls > _minNumberOfControls)
btn_removeAddress.Enabled = true;
if (NumberOfControls < _maxNumberOfControls)
btn_addAddress.Enabled = true;
}
}
protected void addAddress_click(object sender, EventArgs e)
{
if (NumberOfControls < _maxNumberOfControls)
{
AddressInfo addressInfo = (AddressInfo)LoadControl("AddressInfo.ascx");
addressInfo.InitControl(Editable, null);
plc_infoCtrls.Controls.Add(addressInfo);
NumberOfControls++;
}
RefreshButtons();
}
protected void removeAddress_click(object sender, EventArgs e)
{
if (_minNumberOfControls < NumberOfControls)
{
plc_infoCtrls.Controls.RemoveAt(plc_infoCtrls.Controls.Count - 1);
NumberOfControls--;
}
RefreshButtons();
}
}
}
AddressInfo markup
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddressInfo.ascx.cs" Inherits="MFRI.Controls.Contact.AddressInfo" %>
<div>
<asp:Label ID="lbl_line1" AssociatedControlID="txt_line1" runat="server">Line 1:</asp:Label><asp:TextBox ID="txt_line1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator id="val_line1" runat="server" ErrorMessage="Please include a street address" ControlToValidate="txt_line1" Display="Dynamic">*</asp:RequiredFieldValidator>
</div>
<div>
<asp:Label ID="lbl_line2" AssociatedControlID="txt_line2" runat="server">Line 2:</asp:Label><asp:TextBox ID="txt_line2" runat="server"></asp:TextBox>
</div>
<div>
<asp:Label ID="lbl_zip" AssociatedControlID="txt_zip" runat="server">Zip code:</asp:Label><asp:TextBox ID="txt_zip" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator id="val_zip" runat="server" ErrorMessage="Please include a zip code" ControlToValidate="txt_zip" Display="Dynamic">*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator id="regVal_zip" ControlToValidate="txt_zip" ErrorMessage="Zip code must be made up of integers in the format xxxxx" ValidationExpression="^\d{5}$" Runat="server" Display="Dynamic">*</asp:RegularExpressionValidator>
</div>
<div>
<asp:Label ID="lbl_city" AssociatedControlID="txt_city" runat="server">City:</asp:Label><asp:TextBox ID="txt_city" runat="server" CssClass="disabled"></asp:TextBox>
</div>
<div>
<asp:Label ID="lbl_state" AssociatedControlID="ddl_state" runat="server">State:</asp:Label><asp:DropDownList ID="ddl_state" runat="server" Enabled="false"></asp:DropDownList>
</div>
<div>
<asp:Label ID="lbl_edit" AssociatedControlID="chk_edit" runat="server">Edit City/State:</asp:Label><asp:CheckBox ID="chk_edit" runat="server" />
</div>
AddressInfo codebehind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MFRI.Common.Contact;
using System.Text;
using System.Globalization;
using System.Threading;
using MFRI.Common;
namespace MFRI.Controls.Contact
{
public partial class AddressInfo : System.Web.UI.UserControl
{
private bool _editable = false;
private bool _allowStateCityEdit = false;
protected bool AllowStateCityEdit{
set { _allowStateCityEdit = value; }
}
protected ClientScriptManager clientScriptManager
{
get { return Page.ClientScript; }
}
protected void Page_Load(object sender, EventArgs e)
{
txt_city.Attributes.Add("readonly", "readonly");
RegisterEditCityStateScript();
if (_editable)
RegisterZipCodeScript();
}
public void InitControl(bool editable, Address address)
{
InitStateDropDown();
if (!_allowStateCityEdit)
{
lbl_edit.Visible = false;
chk_edit.Visible = false;
}
_editable = editable;
if (!_editable)
{
txt_line1.Enabled = false;
val_line1.Enabled = false;
txt_line2.Enabled = false;
txt_city.Enabled = false;
txt_zip.Enabled = false;
val_zip.Enabled = false;
regVal_zip.Enabled = false;
ddl_state.Enabled = false;
chk_edit.Enabled = false;
}
else
{
txt_zip.Attributes.Add("onblur", "GetCityState('" + txt_city.ClientID + "','" + ddl_state.ClientID + "','" + txt_zip.ClientID + "');");
chk_edit.Attributes.Add("onClick", "ToggleCityState('" + txt_city.ClientID + "','" + ddl_state.ClientID + "','" + txt_zip.ClientID + "')");
}
if (address != null)
{
txt_line1.Text = address.Line1;
txt_line2.Text = address.Line2;
txt_city.Text = address.City;
txt_zip.Text = SafeConvert.ToString(address.Zip);
ddl_state.SelectedValue = SafeConvert.ToString((int)address.State);
}
}
private void RegisterZipCodeScript(){
if (!clientScriptManager.IsClientScriptBlockRegistered(this.GetType(), "zipCodeScript"))
{
StringBuilder script = new StringBuilder();
script.Append("function GetCityState(txtCityId,ddlStateId,txtZipId) {\n");
script.Append(" var textZip = document.getElementById(txtZipId);\n");
script.Append(" var zipCode = parseFloat(textZip.value);\n");
script.Append(" if(isNaN(zipCode)){\n");
script.Append(" var txtCity = document.getElementById(txtCityId);\n");
script.Append(" var ddlState = document.getElementById(ddlStateId);\n");
script.Append(" txtCity.value = '';\n");
script.Append(" ddlState.selectedIndex = 0;\n");
script.Append(" }\n");
script.Append(" else{\n");
script.Append(" MFRI.Controls.Contact.ZipCodeService.GetCityState(zipCode, txtCityId, ddlStateId, SucceededCallback);\n");
script.Append(" }\n");
script.Append("}\n");
script.Append("function SucceededCallback(result) {\n");
script.Append(" var txtCity = document.getElementById(result[0]);\n");
script.Append(" txtCity.value = result[2];\n");
script.Append(" var ddlState = document.getElementById(result[1]);\n");
script.Append(" var stateId = result[3];\n");
script.Append(" for(i=0; i<ddlState.options.length; i++){\n");
script.Append(" if(ddlState.options[i].value == stateId){\n");
script.Append(" ddlState.selectedIndex = i;\n");
script.Append(" }\n");
script.Append(" }\n");
script.Append("}\n");
clientScriptManager.RegisterClientScriptBlock(this.GetType(), "zipCodeScript", script.ToString(), true);
}
}
private void RegisterEditCityStateScript()
{
if (!clientScriptManager.IsClientScriptBlockRegistered(this.GetType(), "editCityState"))
{
StringBuilder script = new StringBuilder();
script.Append("function ToggleCityState(txtCityId, ddlStateId, txtZipId) {\n");
script.Append(" var txtCity = document.getElementById(txtCityId);\n");
script.Append(" var ddlState = document.getElementById(ddlStateId);\n");
script.Append(" if(ddlState.disabled == true){\n");
script.Append(" txtCity.removeAttribute('readonly');\n");
script.Append(" ddlState.disabled = false;\n");
script.Append(" }\n");
script.Append(" else{\n");
script.Append(" txtCity.setAttribute('readonly', 'readonly');\n");
script.Append(" ddlState.disabled = true;\n");
script.Append(" GetCityState(txtCityId,ddlStateId,txtZipId); \n");
script.Append(" }\n");
script.Append("}\n");
clientScriptManager.RegisterClientScriptBlock(this.GetType(), "editCityState", script.ToString(), true);
}
}
private void InitStateDropDown(){
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
ddl_state.Items.Add(new ListItem("Select a state","-1"));
foreach (StateType state in Enum.GetValues(typeof(StateType)))
{
string displayName = state.ToString().ToLower();
displayName = displayName.Replace('_', ' ');
ddl_state.Items.Add(new ListItem(textInfo.ToTitleCase(displayName), state.GetHashCode().ToString()));
}
}
public Address GetAddress()
{
Address address = new Address();
address.Line1 = txt_line1.Text;
address.Line2 = txt_line2.Text;
address.State = (StateType)Enum.ToObject(typeof(StateType), SafeConvert.ToInt(ddl_state.SelectedValue));
address.City = txt_city.Text;
address.Zip = SafeConvert.ToInt(txt_zip.Text);
return address;
}
}
}
I figured it out finally.
Each addressInfo Control is created on the fly by addressInfoGroup. After instantiation, addressInfoGroup calls the 'initControl' method of the newly created addressInfo control. Within that init function I retrieve a few clientID values:
txt_zip.Attributes.Add("onblur", "GetCityState('" + txt_city.ClientID + "','" + ddl_state.ClientID + "','" + txt_zip.ClientID + "');");
chk_edit.Attributes.Add("onClick", "ToggleCityState('" + txt_city.ClientID + "','" + ddl_state.ClientID + "','" + txt_zip.ClientID + "')");
Because of my reference to the clientID's, all of the controls within addressInfo retain the markup Id's. If I comment those lines out, .NET generates the proper Id's. This has something to do with WHEN these lines are called. When I moved the lines into addressInfo's postback, everything worked as expected.
So end result: If a parent control tells a child control to reference a clientID, all of the child controls clientID's seem to malfunction.
Have you thought about using a ListView control to dynamically create and display your Address controls on the fly? You would have one instance of the control hard-coded on the page and then in your ListView's ItemTemplate you would put in your Address control and databind it to the data in your ListView's DataSource property.
Have you tried explicitly setting the ID value of the dynamically added AddressInfo controls? For instance, in the Page_Load of the AddressInfoGroup:
protected void Page_Load(object sender, EventArgs e)
{
if (_controlListToBind != null && _controlListToBind.Count > 0)
{
NumberOfControls = _controlListToBind.Count;
int index = 0;
foreach (Address address in _controlListToBind)
{
AddressInfo addressInfo = (AddressInfo)LoadControl("AddressInfo.ascx");
addressInfo.ID = String.Format("AddressInfo{0}", index++);
addressInfo.InitControl(Editable, address);
plc_infoCtrls.Controls.Add(addressInfo);
}
}
else
{
if (NumberOfControls <= 0)
NumberOfControls = 1;
for (int i = 0; i < NumberOfControls; i++)
{
AddressInfo addressInfo = (AddressInfo)LoadControl("AddressInfo.ascx");
addressInfo.ID = String.Format("AddressInfo{0}", i);
addressInfo.InitControl(Editable, null);
plc_infoCtrls.Controls.Add(addressInfo);
}
}
RefreshButtons();
}