Hej, jag skall validera epost-adress när man vill byta den men vill först också slå upp via mx-record att den finns innan den skickas iväg så att jag inte behöver få meddelanden från servern att adressen inte längre finns. Nåt sånt här, typ? Saknar lite bättre felhantering och du kommer säkert behöva hantera vissa mailservrar/gråfilter som trilskas på olika sätt... YMMV :) Kan tillägga att det här inte ger ett definitivt svar på frågan "är epostadressen asd@foo.bar giltig?". Vissa mailservrar kan t.ex. alltid ge positivt (eller alltid negativt) svar på frågan, oavsett vilken epostadress som används, för att på så sätt försöka lura spammare. Vissa har även tagit bort stödet för verbet VRFY, av samma anledning. Ska du verifiera en hel drös med epostadresser på en gång kan du också råka ut för att du blir grålistad, behandlad som en potentiell spammare och att servern antingen vägrar ha med dig att göra framgent, eller att alla frågor du ställer får en extra fördröjning. Tack Tomas, skall genast prova. Skall bara skriva om till VB som koden är i här så får vi se hur den fungerar. Kommer du på några förbättringar så tveka inte att säga till :)Har någon ett bra MX lookup program?
Jag hittade ett library, http://www.codicode.com/art/free_asp_net_email_validator_verifier.aspx men skulle vilja komma åt hela källkoden för detta så man har bra koll och inte blir beroende av net framework x.x.
Finns det någon som har en bra kod för detta?
//Pelle JohanssonSv: Har någon ett bra MX lookup program?
public class MailUtility
{
// Most of this class was stolen from http://stackoverflow.com/questions/2669841/how-to-get-mx-records-for-a-dns-name-with-system-net-dns
private readonly string _dns;
private readonly string _qtype;
public MailUtility(string dnsServer)
{
_dns = dnsServer;
_qtype = "15"; // MX = 15
}
public void ValidateMailAddress(string lookupaddress)
{
UdpClient udpc = new UdpClient(_dns, 53);
var domain = lookupaddress.Split('@')[1];
// SEND REQUEST--------------------
var list = new List<byte>();
list.AddRange(new byte[]
{
88, 89, // Unique message ID
1, 0, // OPCODE = QUERY, Recursion Desired = 1
0, 1, // QDCOUNT = 1
0, 0, // ANCOUNT = 0
0, 0, // NSCOUNT = 0
0, 0 // ARCOUNT = 0
});
string[] tmp = domain.Split('.');
foreach (string s in tmp)
{
list.Add(Convert.ToByte(s.Length));
char[] chars = s.ToCharArray();
foreach (char c in chars)
list.Add(Convert.ToByte(Convert.ToInt32(c)));
}
list.AddRange(new byte[] { 0, 0, Convert.ToByte(_qtype), 0, 1 });
byte[] req = new byte[list.Count];
for (int i = 0; i < list.Count; i++) { req[i] = list[i]; }
udpc.Send(req, req.Length);
// RECEIVE RESPONSE--------------
IPEndPoint ep = null;
byte[] recv = udpc.Receive(ref ep);
udpc.Close();
var response = new int[recv.Length];
for (int i = 0; i < response.Length; i++)
response[i] = Convert.ToInt32(recv[i]);
int status = response[3];
if (status != 128) throw new Exception(string.Format("{0}", status));
int answers = response[7];
if (answers == 0) throw new Exception("No results");
int pos = domain.Length + 18;
while (answers > 0)
{
int preference = response[pos + 13];
pos += 14; //offset
var mailhost = GetMXRecord(response, pos, out pos);
answers--;
bool isValid = false;
using (var mailer = new MailUtilityClient(mailhost, "test.com"))
{
isValid = mailer.IsMailAddressValid(lookupaddress);
}
Console.WriteLine(string.Format("{0}: {1} - {2}\n", preference, mailhost, isValid));
}
}
private string GetMXRecord(int[] response, int start, out int pos)
{
StringBuilder sb = new StringBuilder();
int len = response[start];
while (len > 0)
{
if (len != 192)
{
if (sb.Length > 0) sb.Append(".");
for (int i = start; i < start + len; i++)
sb.Append(Convert.ToChar(response[i + 1]));
start += len + 1;
len = response[start];
}
if (len == 192)
{
int newpos = response[start + 1];
if (sb.Length > 0) sb.Append(".");
sb.Append(GetMXRecord(response, newpos, out newpos));
start++;
break;
}
}
pos = start + 1;
return sb.ToString();
}
}
public class MailUtilityClient : IDisposable
{
private readonly TcpClient _client;
private readonly NetworkStream _stream;
private readonly string _myIdentifier;
private readonly string _testFromAddress = string.Empty; // Usually not required
private readonly int _receiveWaitTimeoutMs = 200;
public MailUtilityClient(string mailhost, string myIdentifier)
{
_myIdentifier = myIdentifier;
_client = new TcpClient(mailhost, 25);
_stream = _client.GetStream();
var greeting = Get();
Send(string.Format("HELO {0}", _myIdentifier));
}
private string Send(string message)
{
var tcpRequestBuffer = Encoding.ASCII.GetBytes(string.Format("{0}\n", message));
_stream.Write(tcpRequestBuffer, 0, tcpRequestBuffer.Length);
return Get();
}
private string Get()
{
if (!_stream.DataAvailable)
System.Threading.Thread.Sleep(_receiveWaitTimeoutMs);
if (!_stream.DataAvailable)
return string.Empty;
var tcpResponseBuffer = new byte[256];
var responseLength = _stream.Read(tcpResponseBuffer, 0, tcpResponseBuffer.Length);
var responseMsg = Encoding.ASCII.GetString(tcpResponseBuffer, 0, responseLength);
return responseMsg;
}
public bool IsMailAddressValid(string mailAddress)
{
// TODO: attempt to verify address validity using the VRFY verb
Send(string.Format("MAIL FROM:<{0}>", _testFromAddress));
var recipientMessage = Send(string.Format("RCPT TO:<{0}>", mailAddress));
if (string.IsNullOrEmpty(recipientMessage) || recipientMessage.Length < 3)
throw new Exception(string.Format("Unexpected RCPT response: {0}", recipientMessage));
var responseCode = recipientMessage.Substring(0, 3);
return responseCode == "250" || responseCode == "451";
}
public void Dispose()
{
try
{
Send("QUIT");
}
finally
{
if(_stream != null) _stream.Close();
if(_client != null) _client.Close();
}
}
}
För att testa:
var util = new MailUtility("min.dns.com");
util.ValidateMailAddress("asd@foo.bar");
Sv:Har någon ett bra MX lookup program?
Sv:Har någon ett bra MX lookup program?
Som svar på din fråga ovan är det bara att validera en epost-adress när någon skall ändra sin egna här på pellesoft. Tanken är att efter den validerats så skall jag skicka ut ett mail där man får bekräfta sin epost-adress, men jag vill även "innan" det mailet skickas göra en validering. För om den adress de anger är helt fel, så kan jag redan där säga - adressen verkar inte fungera.