Perform Multiple Posts WIth Parallel.ForEach - c#

Here is my syntax, but I keep have a compile error of on my line Parallel.ForEach()
System.Data.DataRow is a type but is used like a variable
which I am sure is something simple that I am just overlooking. Below is my full syntax, if someone could assist me with what exactly I am missing, I will greatly appreciate it!
private void TryParallel()
{
Dictionary<string, string> dic = new Dictionary<string, string>();
string strEndpointURL = string.Format("http://sitetosenddatato.com/post");
SqlDataReader reader;
string strPostData = "";
string strMessage = "";
DataSet grds = new DataSet();
grds = GetSQLResults();
if (grds.Tables[0].Rows.Count >= 1)
{
Parallel.ForEach(DataRow, grds.Tables[0].Rows =>
{
dic.Add("userID", reader.GetValue(0).ToString());
dic.Add("name", reader.GetValue(1).ToString());
dic.Add("address", reader.GetValue(2).ToString());
dic.Add("city", reader.GetValue(3).ToString());
dic.Add("state", reader.GetValue(4).ToString());
dic.Add("zip", reader.GetValue(5).ToString());
dic.Add("Phone", reader.GetValue(6).ToString());
});
}
System.Web.Script.Serialization.JavaScriptSerializer json = new System.Web.Script.Serialization.JavaScriptSerializer();
foreach (var d in dic) { strPostData += d.Key + "=" + Server.UrlEncode(d.Value) + "&"; }
strPostData += "hs_context=";
S ystem.Net.HttpWebRequest r = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strEndpointURL);
r.Method = "POST";
r.Accept = "application/json";
r.ContentType = "application/x-www-form-urlencoded";
r.ContentLength = strPostData.Length;
r.KeepAlive = false;
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(r.GetRequestStream()))
{
try { sw.Write(strPostData); }
catch (Exception ex) { strMessage = ex.Message; }
}
var response = r.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var result = readStream.ReadToEnd();
var xml = System.Xml.Linq.XElement.Parse(result);
if (xml.Elements("success").FirstOrDefault().Value == "1") { strMessage = "Success"; }
else
{
var errors = xml.Elements("errors");
foreach (var error in errors.Elements("error")) { strMessage = error.Value; }
}
}
EDIT
Following the example outlined below by #Glen Thomas - I altered my code to
if (grds.Tables[0].Rows.Count == 1)
{
Parallel.ForEach(rows, row =>
{
dic.Add("userID", reader.GetValue(0).ToString());
//More Here
}
}
which presents a compile error of:
Use of unassigned local variable 'reader'
But I have reader declared at the top of my method?

You are specifying a type name as the first parameter. This should be the collection you are iterating. The second parameter is a function to perform, with a parameter for each element in the collection.
The correct usage of Parallel.ForEach is like this:
var rows = new DataRow[0]
Parallel.ForEach(rows, row =>
{
// Do something with row here
});
For your code:
Parallel.ForEach(grds.Tables[0].Rows.OfType<DataRow>(), row =>
{
dic.Add("userID", reader.GetValue(0).ToString());
dic.Add("name", reader.GetValue(1).ToString());
dic.Add("address", reader.GetValue(2).ToString());
dic.Add("city", reader.GetValue(3).ToString());
dic.Add("state", reader.GetValue(4).ToString());
dic.Add("zip", reader.GetValue(5).ToString());
dic.Add("Phone", reader.GetValue(6).ToString());
});

I believe you want to do this instead:
Parallel.ForEach(grds.Tables[0].Rows.OfType<DataRow>(), (row) =>
{
dic.Add("userID", reader.GetValue(0).ToString());
dic.Add("name", reader.GetValue(1).ToString());
dic.Add("address", reader.GetValue(2).ToString());
dic.Add("city", reader.GetValue(3).ToString());
dic.Add("state", reader.GetValue(4).ToString());
dic.Add("zip", reader.GetValue(5).ToString());
dic.Add("Phone", reader.GetValue(6).ToString());
//though realistically you should be doing something with your specific row
});
The answer is in the error message you recieved - DataRow is not defined as an object in the code you provided.
However, this isn't even actually solving your actual problem which I believe is performing multiple HTTP posts in parallel - so you'd need to put your post logic within the anonymous function of your Parallel.ForEach()

Related

How can I write the result to the csv?

I want to ping the hostnames that are in the csv and write the result in the next column, but I'm little bit lost how to do it?
This the error I get:Error CS0021 Cannot apply indexing with [] to an expression of type 'StreamReader'
And the only thing I can do is write to the console what is in the csv.
string filePath = #"c:\hostnames.csv";
var reader = new StreamReader(filePath);
Ping ping = new Ping();
List<string> hostnames = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
hostnames.Add(values[0]);
hostnames.ForEach(Console.WriteLine);
}
List<string> goodPing = new List<string>();
foreach (string singleComputer in hostnames)
{
PingReply pingresult = ping.Send(singleComputer);
if (pingresult.Status.ToString() == "Success")
{
goodPing.Add(singleComputer);
}
}
var csv = new StringBuilder();
var first = reader[0].ToString();
var newLine = string.Format("{0}");
csv.AppendLine(newLine);
File.WriteAllText(filePath, csv.ToString());
}
It is not clear what error you are getting is but one issue I noticed is you are not providing a variable to string.Format which I think it is useless at there..
Example hostnames.csv is something like this I assume:
www.google.com,www.somebadu-rlwhichcannot..com,www.stackoverflow.com
var filePath = #"c:\test\hostnames.csv"; // change it to your source
var filePathOutput = #"c:\test\hostnamesOutput.csv"; // use separate output file so you would not overwrite your source..
var ping = new Ping();
var hostNames = new List<string>();
using (var reader = new StreamReader(filePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
hostNames = line.Split(',').ToList();
}
}
var goodPing = new List<string>();
foreach (var singleComputer in hostNames)
try
{
var pingResult = ping.Send(singleComputer);
if (pingResult.Status == IPStatus.Success)
{
goodPing.Add(singleComputer);
}
}
catch (Exception e)
{
// host was not in a correct format or any other exception thrown....
// do whatever error handling you want, logging etc...
}
var csv = new StringBuilder();
foreach (var hostname in hostNames)
{
var resultText = goodPing.Contains(hostname) ? "Success" : "Failed";
var newLine = string.Format("{0},{1}", hostname, resultText);
csv.AppendLine(newLine);
}
File.WriteAllText(filePathOutput, csv.ToString());
I didn't try on IDE but it should be doing what you are trying to do. Seems you copy pasted that code from somewhere and tried to manipulate it without understanding. I would suggest to make sure you understand it line by line why it is used, how it is used before you start using it. Otherwise you will always need someone to write the code for you!
Output will be (in excel):
Here is a simplified version of what I think you are trying to do.
Example hostheaders.csv before code runs
www.google.com
www.stackoverflow.com
www.fakewebsitehere.com
Updated code
string filePath = #"c:\hostnames.csv";
List<string> results = new List<string>();
using (var reader = new StreamReader(filePath))
{
Ping ping = new Ping();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
var hostname = values[0];
Console.WriteLine(hostname);
PingReply pingresult = ping.Send(hostname);
results.Add($"{line},{pingresult.Status.ToString()}");
}
}
File.WriteAllLines(filePath, results);
hostheaders.csv after code runs
www.google.com,Success
www.stackoverflow.com,Success
www.fakewebsitehere.com,TimedOut

Instagram API: How to insert all user media in c# asp.net mvc?

I am trying the get all user media from the instagram api and store into database but how can do that i don't know. i am write the code but using this code just add one media in the database. any one have the idea then please let me know how can do that. here below list the my code.
This is my C# method :
public string makePostFromInstagram()
{
var serializer1 = new System.Web.Script.Serialization.JavaScriptSerializer();
var nodes1 = serializer1.Deserialize<dynamic>(GetData(strInstagramUserId));
foreach (var date in nodes1)
{
if (date.Key == "data")
{
string theKey = date.Key;
var thisNode = date.Value;
int userCount = 0;
foreach (var post in thisNode)
{
if (thisNode[userCount]["username"] == strInstagramUserId)
{
id = thisNode[userCount]["id"].ToString();
}
userCount++;
}
}
}
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
Dictionary<string, object> csObj = serializer.Deserialize<Dictionary<string, object>>(GetRecentPost(id, accessToken));
int length = ((ArrayList)csObj["data"]).Count;
var nodes = serializer.Deserialize<dynamic>(GetRecentPost(id, accessToken));
foreach (var date in nodes)
{
if (date.Key == "data")
{
string theKey = date.Key;
var thisNode = date.Value;
foreach (var post in thisNode)
{
UsersOnInstagram objUserInsta = new UsersOnInstagram();
string result = null;
//here i am add just one image so i want to here add multiple image insert
if (post["type"] == "image")
result = UsersOnInstagram.addInstagramPost(strPtId, HttpUtility.UrlEncode(post["caption"]["text"]), post["images"]["standard_resolution"]["url"], UnixTimeStampToDateTime(Convert.ToDouble(post["created_time"])), null, post["type"]);
else if (post["type"] == "video")
result = objUserInsta.addInstagramPost(HttpUtility.UrlEncode(post["caption"]["text"]), strPtId, post["images"]["standard_resolution"]["url"], UnixTimeStampToDateTime(Convert.ToDouble(post["created_time"])), post["videos"]["standard_resolution"]["url"], post["type"]);
}
}
}
Response.End();
}
this is my api method :
public static string GetRecentPost(string instagramaccessid, string instagramaccesstoken)
{
Double MAX_TIMESTAMP = DateTimeToUnixTimestamp(DateTime.Today.AddDays(-1));
Double MIN_TIMESTAMP = DateTimeToUnixTimestamp(DateTime.Today.AddDays(-2));
string url = "https://api.instagram.com/v1/users/" + instagramaccessid + "/media/recent?access_token=" + instagramaccesstoken + "&min_timestamp=" + MIN_TIMESTAMP + "&maz_timestamp=" + MAX_TIMESTAMP;
var webClient = new System.Net.WebClient();
string d = webClient.DownloadString(url);
return d;
}
any one know how can do that please let me know.

how to return datatable and integer in c#

I am creating a method which returns datatable and an int value.I have create a method which returns only datatable.Please take a look on the code
public static DataTable ShutterstockSearchResults(string url)
{
int TotalCont=0;
DataTable dt = new DataTable();
try
{
//intigration using Basic Aouth with authrization headers
var request = (HttpWebRequest)WebRequest.Create(url);
var username = "SC";
var password = "SK";
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
request.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}", credentials);
request.UserAgent = "MyApp 1.0";
var response = (HttpWebResponse)request.GetResponse();
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
JavaScriptSerializer js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
SearchResult myojb = (SearchResult)js.Deserialize(objText, typeof(SearchResult));
TotalCount = myojb.total_count;
dt.Columns.Add("Id");
dt.Columns.Add("Discription");
dt.Columns.Add("Small_Thumb_URl");
dt.Columns.Add("Large_Thumb_URL");
dt.Columns.Add("Prieview_URL");
dt.Columns.Add("ContributorID");
dt.Columns.Add("aspect");
dt.Columns.Add("image_type");
dt.Columns.Add("is_illustration");
dt.Columns.Add("media_type");
foreach (var item in myojb.data)
{
var row = dt.NewRow();
row["ID"] = item.id;
row["Discription"] = item.description;
row["Small_Thumb_URl"] = item.assets.small_thumb.url;
row["Large_Thumb_URL"] = item.assets.large_thumb.url;
row["Prieview_URL"] = item.assets.preview.url;
row["ContributorID"] = item.contributor.id;
row["aspect"] = item.aspect;
row["image_type"] = item.image_type;
row["is_illustration"] = item.is_illustration;
row["media_type"] = item.media_type;
dt.Rows.Add(row);
}
// List<SearchResult> UserList = JsonConvert.DeserializeObject<List<SearchResult>>(objText);
// Response.Write(reader.ReadToEnd());
}
}
catch (WebException ea)
{
Console.WriteLine(ea.Message);
using (var stream = ea.Response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
return dt;
}
I want to return datatable and TotalCont.please help
Generally speaking, a method can only return one type.
You have two options:
1) Create a class that has a DataTable and an int field, such as:
public class MyReturnType
{
public DataTable TheDataTable {get; set;}
public int TotalCount {get; set;}
}
And return this type from your method.
2) You can add an out parameter to your method:
public static DataTable ShutterstockSearchResults(string url, out totalCount)
And assign to totalCount within your method.
public static Tuple<DataTable, int> ShutterstockSearchResults(string url)
{
[...]
return new Tuple<DataTable, int>(dt, totalCount);
}
public static void SomeConsumerMethod()
{
var result = ShutterstockSearchResults(myPath);
DataTable dt = result.Item1;
int totalCount = result.Item2;
}
To answer the comments in Klaus answer:
public class MyReturnType
{
public DataTable TheDataTable {get; set;}
public int TotalCount {get; set;}
}
and in your method:
public static MyReturnType ShutterstockSearchResults(string url)
{
MyReturnType result=new MyReturnType();
int TotalCont=0;
DataTable dt = new DataTable();
try
{
//intigration using Basic Aouth with authrization headers
var request = (HttpWebRequest)WebRequest.Create(url);
var username = "SC";
var password = "SK";
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
request.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}", credentials);
request.UserAgent = "MyApp 1.0";
var response = (HttpWebResponse)request.GetResponse();
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
JavaScriptSerializer js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
SearchResult myojb = (SearchResult)js.Deserialize(objText, typeof(SearchResult));
TotalCount = myojb.total_count;
dt.Columns.Add("Id");
dt.Columns.Add("Discription");
dt.Columns.Add("Small_Thumb_URl");
dt.Columns.Add("Large_Thumb_URL");
dt.Columns.Add("Prieview_URL");
dt.Columns.Add("ContributorID");
dt.Columns.Add("aspect");
dt.Columns.Add("image_type");
dt.Columns.Add("is_illustration");
dt.Columns.Add("media_type");
foreach (var item in myojb.data)
{
var row = dt.NewRow();
row["ID"] = item.id;
row["Discription"] = item.description;
row["Small_Thumb_URl"] = item.assets.small_thumb.url;
row["Large_Thumb_URL"] = item.assets.large_thumb.url;
row["Prieview_URL"] = item.assets.preview.url;
row["ContributorID"] = item.contributor.id;
row["aspect"] = item.aspect;
row["image_type"] = item.image_type;
row["is_illustration"] = item.is_illustration;
row["media_type"] = item.media_type;
dt.Rows.Add(row);
}
// List<SearchResult> UserList = JsonConvert.DeserializeObject<List<SearchResult>>(objText);
// Response.Write(reader.ReadToEnd());
}
}
catch (WebException ea)
{
Console.WriteLine(ea.Message);
using (var stream = ea.Response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
result.TheDataTable=dt;
result.TotalCount=TotalCount;
return result:
}
Your method needs an additional out parameter if you want to "return" more than one value. Just pass an uninitialized variable of the desired type into your method and assign that variable inside.
public void Test()
{
int i;
DataTable ShutterstockSearchResults("Some string", out i);
}
your ShutterstockSearchResults method needs to be modified accordingly:
public static DataTable ShutterstockSearchResults(string url, out int outParam)
{
outParam = 10;
// do other stuff
}
If you do not change outParam any further inside ShutterstockSearchResults, it will have the value 10 after returning to Test.
You can accomplish this with a Tuple. Consider the following simple example:
public class EmptyClass
{
public static void Main(){
EmptyClass something = new EmptyClass ();
Tuple<String, int> tuple = something.returnMe ();
Console.WriteLine ("Item 1: " + tuple.Item1);
Console.WriteLine ("Item 2: " + tuple.Item2);
}
public EmptyClass ()
{
}
public Tuple<String, int> returnMe() {
return Tuple.Create ("Hello", 2);
}
}

What is an easy way to write the results of an SQL query to a Web Forms Response in ASP.NET?

I need an easy way to write the results of an SQL query (SQLDataReader via sqlcommand.ExecuteReader()) to a Web Forms Response (i.e., some string written to Response.Write(string)) and in a format that is easy to read in PHP. I was thinking of creating a JSON Object, converting that to a string, and writing that JSON string to a response, but I can't find an easy way to do that in Web Forms.
I'm thinking something like:
{ "tableColumn1": "value",
"tableColumn2": "value"}
but I'm not sure if there's an easy way to do this using an SqlDataReader.
The ultimate goal is to make often-evolving table data in a .NET environment easily accessible to read in a Linux environment using PHP.
public class myClass
{
public int myColumn { get; set; }
public string myColumn2 { get; set; }
}
public string MySqlMethod()
{
using (var conn = new SqlConnection("connectionString"))
{
var query = "SELECT * FROM SomeTable;";
var cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
var listToConvert = new List<myClass>();
while (dr.Read())
{
var toAdd = new myClass();
toAdd.myColumn = dr.GetInt32(dr.GetOrdinal("myColumn"));
toAdd.myColumn2 = dr.GetString(dr.GetOrdinal("myColumn2"));
listToConvert.Add(toAdd);
}
return GenerateJson(listToConvert);
}
}
public static string GenerateJson<T>(List<T> obj)
{
var returnString = "[";
var listCounter = 0;
foreach (var item in obj)
{
var counter = 0;
var props = item.GetType().GetProperties();
returnString += "{";
foreach (var prop in props)
{
returnString += "\"" + prop.Name + "\":" + "\"" + prop.GetValue(item, null) + "\"";
counter++;
if (counter != props.Count())
returnString += ",";
}
returnString += "}";
listCounter++;
if (listCounter != obj.Count())
returnString += ",";
}
returnString += "]";
return returnString;
}
This is completely 'doable' in WebForms, this isn't specific to MVC.
The upkeep on this is pretty simple, a minor change to the custom class and, some new dr.GetWhatever when the table changes.
If you want a more dynamic solution, I would look into the Entity Framework, if possible. Then you can just create partial classes that compliment the auto-generated ones that EF makes. The upkeep is almost null at that point.
In Page_Load event, you need to clear the response and then handle it manually, using below codes :
string response = string.Format("[ \"tableColumn1\": \"{0}\",\"tableColumn2\":\"{2}\"]", value1, value2).Replace('[', '{').Replace(']', '}');
Response.Clear();
Response.ContentType = "application/json; charset=utf-8";
Response.Write(response );
Response.End();

How to update ObservableCollection when i call the same URL?

I have problem, i don't know how to update ObservableCollection when i call the same URL in windows phone.
The problem is:-
I call the URL for the first time then i add this to my listbox then after one minute i call the same URL and the result have new data (New data Added or Old Data removed), i don't how to search the old data to check if all new data is exist and if not how add the new row received with out duplication.
Please Advise me :(
this how i call the URL and how i add the data:-
private void GetOpentPos (Object sender, EventArgs e)
{
var request = HttpWebRequest.Create(new Uri("http://74.54.46.178/vertexweb10/webservice.svc/GetOpenPositions?AccountId=1122336675")) as HttpWebRequest;
request.Method = "GET";
if (request.Headers == null)
{
request.Headers = new WebHeaderCollection();
}
request.Headers[HttpRequestHeader.IfModifiedSince] = DateTime.UtcNow.ToString();
request.CookieContainer = cookieJar2;
request.BeginGetResponse(ar =>
{
HttpWebRequest req2 = (HttpWebRequest)ar.AsyncState;
using (var response = (HttpWebResponse)req2.EndGetResponse(ar))
{
using (Stream stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
var outerRoot4 = JsonConvert.DeserializeObject<OuterRootObject4>(reader.ReadToEnd());
JArray jsonArray = JArray.Parse(outerRoot4.d);
JToken jsonArray_Item = jsonArray.First;
DispatchInvoke(() =>
{
while (jsonArray_Item != null)
{
string SymbolNameTra = jsonArray_Item.Value<string>("SymbolName");
string TypeTra = jsonArray_Item.Value<string>("BuySell");
double AmountTra = jsonArray_Item.Value<double>("Amount");
double ProfitLossTra = jsonArray_Item.Value<double>("ProfitLoss");
int PosID = jsonArray_Item.Value<int>("ID");
DataReceivedCollectionTr.Add(new DataTr() { SymbolNameTr = SymbolNameTra, TypeTr = TypeTra, AmountTr = AmountTra, ProfitLossTr = ProfitLossTra,PosID = PosID });
jsonArray_Item = jsonArray_Item.Next;
}
}
);
}
}
}
}, request);
}
Check by some unique field and if list does not containt such item add it
if (DataReceivedCollectionTr.FirstOrDefault(i => i.SymbolNameTr == SymbolNameTra) == null)
{
DataReceivedCollectionTr.Add(new DataTr() { SymbolNameTr = SymbolNameTra, TypeTr = TypeTra, AmountTr = AmountTra, ProfitLossTr = ProfitLossTra,PosID = PosID });
}

Categories