# Import Yahoo Contacts in C#

I have the following code for importing Yahoo contacts from an address book, but it imports only the top 30 contacts, not all of the contacts.

Anyways, I think another alternative (and better) way of doing it is by using another latest Yahoo API.

        private const string _addressBookUrl = "http://address.mail.yahoo.com/allcontacts";
private const string _userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3";

[TestMethod()]
public void Yahoo()
{
List<ContactDetails> lst = new List<ContactDetails>();
Assert.IsNotNull(lst);
}

public List<ContactDetails> GetYahooContacts(string _username, string _pass)
{
try
{
WebClient webclient = new WebClient();
webclient.Encoding = Encoding.UTF8;

string firstRes = Encoding.UTF8.GetString(firstResponse);

Regex regex = new Regex("type=\"hidden\" name=\"(.*?)\" value=\"(.*?)\"", RegexOptions.IgnoreCase);
Match match = regex.Match(firstRes);
while (match.Success)
{
if (match.Groups[0].Value.Length > 0)
{
}
match = regex.Match(firstRes, match.Index + match.Length);
}

webclient.Encoding = Encoding.UTF8;

foreach (string var in tmp1)
{
string[] tmp2 = var.Split(';');
}

string thirdRes = Encoding.UTF8.GetString(thirdResponse);
List<ContactDetails> lst = new List<ContactDetails>();
lst = ParseYahooResponse(thirdRes);
return lst;
}
catch (Exception e)
{
throw e;
}
}

private List<ContactDetails> ParseYahooResponse(string _response)
{
List<ContactDetails> ContactList = new List<ContactDetails>();
_response = _response.Substring(_response.IndexOf("InitialContacts"), (_response.IndexOf("InitialBucket") - _response.IndexOf("InitialContacts")));

List<YahooContacts> Contacts = JsonConvert.DeserializeObject<List<YahooContacts>>(_response.Substring(_response.IndexOf('['), (_response.LastIndexOf(']') - _response.IndexOf('[')) + 1));

foreach (YahooContacts oYahooContacts in Contacts)
{
ContactDetails ocontacts = new ContactDetails();
ocontacts.Name = Convert.ToString(oYahooContacts.ContactName);

}
return ContactList;
}
}

public class YahooContacts
{
private string contactId;
private string contactName;
private string email;

public string ContactID
{
get { return contactId; }
set { contactId = value; }
}

public string ContactName
{
get { return contactName; }
set { contactName = value; }
}

public string Email
{
get { return email; }
set { email = value; }
}
}


Any suggestions?

These are bad variable names, they should be descriptive of what kind of values they contain:

string[] tmp1 = cookie.Split(',');
string[] tmp2 = var.Split(';');


Moreover, tmp1 isn't even necessary since you only use it once.

Also avoid things like oYahooContacts, just name them yahooContacts.

Don't abbreviate, e.g. _pass. It isn't necessary and only makes code harder to read.

I don't think ParseYahooResponse is descriptive enough. Sure, that method does parse the response, but more importantly it returns a list of contacts.

Variables should be camelCase:

List<ContactDetails> ContactList = new List<ContactDetails>();
List<YahooContacts> Contacts


I don't think YahooContacts is a good class name, for one it is a plural. It can also be simplified by using Auto-Implemented Properties, e.g.

public string ContactID {get;set;}


Things like private const string _addressBookUrl belong in a separate class IMHO, or perhaps in a config file.

Why do you name your parameter _username and then assign it to the variable login? Plus in your test method you call it "UserId".

I'm not a fan of this:

postToLogin.Add(".save", "Sign In");


This reeks of magic strings. I would be tempted to make this a class of its own, which then can be converted to a NameValueCollection, and things like ".save" would be constants in that class, perhaps.

At least I'd move the whole postToLogin logic to its own class, have it parse the response and return a NameValueCollection.

Actually, that goes for most of the code. I'd move some code from GetYahooContacts at least to separate methods, certainly the lines where you create a new cookie. The whole method is rather hard to figure out, for instance I didn't quite understand why you assigned to webclient.Headers[HttpRequestHeader.Cookie] multiple times until I noticed webclient.UploadValues(_authUrl, postToLogin); happens between those two assignments.

I'd much prefer it if the logic in that method was distributed over several shorter method, so the logic becomes clearer, e.g. do a download, parse the response/create the postToLogin NameValueCollection, do an upload, create the cookie, do a download, get the contact details.

I don't have a whole lot of time right now, but I noticed this while scanning through your code.

      catch (Exception e)
{
throw e;
}


There's no point in catching an exception just to re throw it. This adds unnecessary overhead to the code. You might as well just remove the try...catch block.