2009-06-13 13 views
8

Ho un progetto che invierà un'e-mail con determinati dati a un account Gmail. Penso che sarà probabilmente più facile leggere il feed Atom piuttosto che connettersi tramite POP.Leggere il feed Atom dell'account Gmail da C#

l'URL che dovrei usare secondo Google è:

https://gmail.google.com/gmail/feed/atom 

La domanda/problema è: come faccio a autenticare l'account di posta elettronica che voglio vedere? Se lo faccio in Firefox, utilizza i cookie.

Sono anche incerto su come esattamente "scaricare" il file XML che questa richiesta dovrebbe restituire (credo che il termine corretto sia lo stream).

Edit 1:

Sto usando .Net 3.5.

+0

Il codice che ho scritto deve funzionare idealmente, ma credo che ci sia qualche problema con il metodo di autenticazione di Google, immagino. Questo tipo sembra avere lo stesso problema - http://objectmix.com/xml-soap/336644-problem-reading-gmail-atom-feed-net.html – Kirtan

risposta

6

Questo è quello che ho usato in Vb.net:

objClient.Credentials = New System.Net.NetworkCredential(username, password) 

objClient è di tipo System.Net.WebClient.

È quindi possibile ottenere i messaggi di posta elettronica dal feed utilizzando qualcosa di simile:

Dim nodelist As XmlNodeList 
Dim node As XmlNode 
Dim response As String 
Dim xmlDoc As New XmlDocument 

'get emails from gmail 
response = Encoding.UTF8.GetString(objClient.DownloadData("https://mail.google.com/mail/feed/atom")) 
response = response.Replace("<feed version=""0.3"" xmlns=""http://purl.org/atom/ns#"">", "<feed>") 

'Get the number of unread emails 
xmlDoc.LoadXml(response) 
node = xmlDoc.SelectSingleNode("/feed/fullcount") 
mailCount = node.InnerText 
nodelist = xmlDoc.SelectNodes("/feed/entry") 
node = xmlDoc.SelectSingleNode("title") 

Questo non dovrebbe essere molto diverso in C#.

+0

Grazie, provo quando torno a casa – Crash893

+0

Ricevo un errore "(407) Autenticazione proxy richiesta" quando eseguo questo codice, qualcun altro ha provato? – ryanulit

+0

È strano. Io uso quel codice in un'app che uso quotidianamente al lavoro. L'unico modo che potresti ottenere sarebbe se Google modificasse qualcosa sulla sua fine, che dubito (non hanno cambiato nulla nell'anno in cui ho usato la mia app). – alex

6

.NET framework 3.5 fornisce classi native per leggere i feed. This articoli descrive come farlo.

Non l'ho ancora usato, ma ci deve essere qualche disposizione per l'autenticazione di un URL. Puoi verificarlo. Anch'io lo farò e rispedirò la risposta.

Se non si utilizza framework 3.5, è possibile provare Atom.NET. L'ho usato una volta, ma è vecchio. Puoi fare un tentativo se soddisfa le tue esigenze.

EDIT: Questo è il codice per l'assegnazione di credenziali utente:

XmlUrlResolver resolver = new XmlUrlResolver(); 
resolver.Credentials = new NetworkCredential("[email protected]", "password"); 

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.XmlResolver = resolver; 

XmlReader reader = XmlReader.Create("https://gmail.google.com/gmail/feed/atom", settings); 
+0

questo codice funziona bene grazie - come dichiarato da Matthew Flaschen restituisce un errore 401 che suppongo di aver bisogno di inviare l'autenticazione in qualche modo. Qualcuno ha qualche idea su questo? – Crash893

2

Si utilizza Auth di base. Fondamentalmente, si effettua una richiesta iniziale, il server risponde con 401 e quindi si restituisce la password in base64 (in questo caso su HTTPS).

Nota però che:

  1. Il feed consente solo di ottenere informazioni circa la banale considerazione (ad esempio nuovi messaggi). Non ti permette di inviare messaggi.
  2. POP non può essere utilizzato per inviare messaggi.
  3. In genere viene utilizzato SMTP e non è così difficile.

MODIFICA: ecco un esempio per l'autenticazione e il caricamento del feed Atom in un XmlDocument. Nota però che fornirà solo l'accesso in lettura. Cerca o fai un'altra domanda per informazioni su C# e SMTP. La junk ICertificatePolicy era necessaria per me visto che a Mono non piaceva il certificato di Google. È una soluzione rapida, non adatta alla produzione.

OK, poiché hai chiarito che stai effettivamente leggendo la posta (e un componente diverso la sta inviando), ti consiglio di utilizzare POP. :

using System; 
using System.Net; 
using System.IO; 
using System.Security.Cryptography.X509Certificates; 
using System.Xml; 

public class GmailFeed 
{ 
    private class IgnoreBadCerts : ICertificatePolicy 
    { 
     public bool CheckValidationResult (ServicePoint sp, 
              X509Certificate certificate, 
              WebRequest request, 
              int error) 
     { 
      return true; 
     } 


    } 

    public static void Main(string[] argv) 
    { 
     if(argv.Length != 2) 
     { 
      Console.Error.WriteLine("Usage: GmailFeed username password"); 
      Environment.ExitCode = 1; 
      return; 
     } 
     ServicePointManager.CertificatePolicy = new IgnoreBadCerts(); 

     NetworkCredential cred = new NetworkCredential(); 
     cred.UserName = argv[0]; 
     cred.Password = argv[1]; 

     WebRequest req = WebRequest.Create("https://gmail.google.com/gmail/feed/atom"); 
     req.Credentials = cred; 
     Stream resp = req.GetResponse().GetResponseStream(); 

     XmlReader reader = XmlReader.Create(resp); 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(reader); 
    } 
} 
+0

potresti pubblicare un esempio Sono davvero all'oscuro su come fare questo – Crash893

+0

l'account verrà utilizzato solo come un sistema a senso unico. in pratica i cavi GPS vengono inviati sotto forma di posta. poi ho bisogno di raccoglierli e leggerli Grazie per il codice lo proverò – Crash893

+0

Ricevo di nuovo lo stesso errore. Ho confuso che in yoru post hai menzionato l'invio della password in base64 ma nel codice non vedo questo anche come chiedi una pagina e poi rispondi alla pagina per dare la password base64? – Crash893

1

Per quello che il suo valore, non sono mai stato in grado di autheniticate via:

https://gmail.google.com/gmail/feed/atom 

Comunque posso sempre autenticarsi su:

https://mail.google.com/mail/feed/atom 

HTH !!

0

Ecco il mio magro e avaro soluzione:

public static string TextToBase64(string sAscii) 
    { 
     System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); 
     byte[] bytes = encoding.GetBytes(sAscii); 
     return System.Convert.ToBase64String(bytes, 0, bytes.Length); 
    } 

    public static void foobar() 
    { 
     var url = @"https://gmail.google.com/gmail/feed/atom"; 

     var USER = "userName"; 
     var PASS = "password"; 

     var encoded = TextToBase64(USER + ":" + PASS); 

     var myWebRequest = HttpWebRequest.Create(url); 
     myWebRequest.Method = "POST"; 
     myWebRequest.ContentLength = 0; 
     myWebRequest.Headers.Add("Authorization", "Basic " + encoded); 

     var response = myWebRequest.GetResponse(); 
     var stream = response.GetResponseStream(); 

     // Parse the stream using your favorite parsing library or using XmlDocument ... 
    } 
+1

Restituisce l'errore 401 – Reynevan

1

Il seguente metodo sembra funzionare per controllare la quantità di messaggi non letti. Non ne so molto di XML quindi non sono stato in grado di analizzare i risultati se non quello di recuperare il conteggio non letto. (Restituisce -1 per errore)

public int GmailUnreadCount(string username, string password) 
    { 
     XmlUrlResolver resolver = new XmlUrlResolver(); 
     resolver.Credentials = new NetworkCredential(username, password); 
     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.XmlResolver = resolver; 
     try 
     { 
      XmlReader reader = XmlReader.Create("https://mail.google.com/mail/feed/atom", settings); 
      while (reader.Read()) 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         switch (reader.Name) 
         { 
          case "fullcount": 
           int output; 
           Int32.TryParse(reader.ReadString(), out output); 
           return output; 
         } 
         break; 
       } 
      } 
     } 
     catch (Exception a) 
     { 
      MessageBox.Show(a.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      return -1; 
     } 
     return -1; 
    } 
Problemi correlati