Use reflection-based SafeGet for Outlook COM property reading

Dynamic COM with ?? operator can fail silently for properties
that return COM null vs .NET null. Use GetType().InvokeMember()
which reliably reads any Outlook property and catches COM errors
per field instead of crashing the whole contact read.

Fixes Fax and other fields that may not have been read correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 18:54:10 +02:00
parent 9007e2a9b5
commit 7ffaddc77f
@@ -394,29 +394,40 @@ namespace StarfaceOutlookSync.Services
}
}
private static string SafeGet(dynamic ci, string property)
{
try
{
object val = ci.GetType().InvokeMember(property,
System.Reflection.BindingFlags.GetProperty, null, ci, null);
return val?.ToString() ?? "";
}
catch { return ""; }
}
private UnifiedContact MapFromOutlook(dynamic ci)
{
return new UnifiedContact
{
OutlookEntryId = (string)(ci.EntryID ?? ""),
FirstName = (string)(ci.FirstName ?? ""),
LastName = (string)(ci.LastName ?? ""),
Company = (string)(ci.CompanyName ?? ""),
JobTitle = (string)(ci.JobTitle ?? ""),
Email = (string)(ci.Email1Address ?? ""),
EmailSecondary = (string)(ci.Email2Address ?? ""),
PhoneWork = (string)(ci.BusinessTelephoneNumber ?? ""),
PhoneMobile = (string)(ci.MobileTelephoneNumber ?? ""),
PhoneHome = (string)(ci.HomeTelephoneNumber ?? ""),
Fax = (string)(ci.BusinessFaxNumber ?? ""),
Street = (string)(ci.BusinessAddressStreet ?? ""),
City = (string)(ci.BusinessAddressCity ?? ""),
PostalCode = (string)(ci.BusinessAddressPostalCode ?? ""),
State = (string)(ci.BusinessAddressState ?? ""),
Country = (string)(ci.BusinessAddressCountry ?? ""),
Website = (string)(ci.WebPage ?? ""),
Notes = (string)(ci.Body ?? ""),
Salutation = (string)(ci.Title ?? ""),
OutlookEntryId = SafeGet(ci, "EntryID"),
FirstName = SafeGet(ci, "FirstName"),
LastName = SafeGet(ci, "LastName"),
Company = SafeGet(ci, "CompanyName"),
JobTitle = SafeGet(ci, "JobTitle"),
Email = SafeGet(ci, "Email1Address"),
EmailSecondary = SafeGet(ci, "Email2Address"),
PhoneWork = SafeGet(ci, "BusinessTelephoneNumber"),
PhoneMobile = SafeGet(ci, "MobileTelephoneNumber"),
PhoneHome = SafeGet(ci, "HomeTelephoneNumber"),
Fax = SafeGet(ci, "BusinessFaxNumber"),
Street = SafeGet(ci, "BusinessAddressStreet"),
City = SafeGet(ci, "BusinessAddressCity"),
PostalCode = SafeGet(ci, "BusinessAddressPostalCode"),
State = SafeGet(ci, "BusinessAddressState"),
Country = SafeGet(ci, "BusinessAddressCountry"),
Website = SafeGet(ci, "WebPage"),
Notes = SafeGet(ci, "Body"),
Salutation = SafeGet(ci, "Title"),
Birthday = GetBirthdayString(ci)
};
}
@@ -425,8 +436,9 @@ namespace StarfaceOutlookSync.Services
{
try
{
DateTime bday = ci.Birthday;
if (bday.Year > 1900 && bday != DateTime.MinValue)
object val = ci.GetType().InvokeMember("Birthday",
System.Reflection.BindingFlags.GetProperty, null, ci, null);
if (val is DateTime bday && bday.Year > 1900 && bday != DateTime.MinValue)
return bday.ToString("yyyy-MM-dd");
}
catch { }