2020年5月28日 星期四

將字串從某個關鍵字串截斷,只保留關鍵字串前面的部分

 public static string 截斷(this string text, string 關鍵字)
        {
            if (text != default && text.Contains(關鍵字)) return System.Text.RegularExpressions.Regex.Split(text, 關鍵字)[0];
            else return text;
        }

2020年5月22日 星期五

用程式讀取 exchange server 信箱

1. 安裝套件: Microsoft.Exchange.WebServices
2. 讀取信箱
var es = new Microsoft.Exchange.WebServices.Data.ExchangeService(ExchangeVersion.Exchange2010_SP1);
es.Credentials = new Microsoft.Exchange.WebServices.Data.WebCredentials(帳號, 密碼, 網域);
es.Url = new Uri("https://.../ews/Exchange.asmx"); // Server路徑
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; // 確保登入信箱不會失敗
SearchFilter.SearchFilterCollection searchFilterCollection = new SearchFilter.SearchFilterCollection(LogicalOperator.And); // 設定條件類型為全部還是任一
                                            searchFilterCollection.Add(new SearchFilter.IsGreaterThan(EmailMessageSchema.DateTimeReceived, 上次資料時間)); // 加入條件
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties); // 為了讀取內文
itempropertyset.RequestedBodyType = BodyType.Text;
ItemView itemview = new ItemView(1000);
itemview.PropertySet = itempropertyset;
var elements = es.FindItems(WellKnownFolderName.Inbox, searchFilterCollection, itemview).Where(a => a is EmailMessage).ToList(); // 尋找收件匣信件 (WellKnownFolderName.SentItems : 寄件備份)
foreach (EmailMessage email in elements ) // 轉型為 EmailMessage
{
email.Load(itempropertyset); // 為了讀取內文
email.From.Address : 寄件者
email.ToRecipients、email.DisplayTo : 收件者
email.Body.Text : 內文
email.InternetMessageId : 透過此欄位可找出回信
email.InReplyTo : 若為寄件備份且是回信,等於來源信件 InternetMessageId
email.Id.UniqueId : id
                 
依據id 找出單一信件:
EmailMessage.Bind(es, new ItemId(id));                      

取得附件檔案
public static IEnumerable<(string 檔名, byte[] 檔案內容)> 取得附加檔案(this Microsoft.Exchange.WebServices.Data.EmailMessage email)
        {
            foreach (var attachment in email.Attachments.OrderByDescending(a => a.Size))
            {
                if (attachment is Microsoft.Exchange.WebServices.Data.FileAttachment && !attachment.IsInline)
                {
                    Microsoft.Exchange.WebServices.Data.FileAttachment 附件檔案 = attachment as Microsoft.Exchange.WebServices.Data.FileAttachment;
                    using (var mem = new System.IO.MemoryStream())
                    {
                        附件檔案.Load(mem);
                        yield return (附件檔案.Name, mem.ToArray());
                    }
                }
            }
            yield return default;
        }


若要存取 Exchange Online 雲端信箱 ,認證方式較為複雜
1. 參考此網址,於 server 註冊應用程式提供授權
2. 設定證書及信箱語法如下
var cca = Microsoft.Identity.Client.ConfidentialClientApplicationBuilder
.Create(應用程式識別碼)
.WithClientSecret(用戶端密碼) // 最多可設兩年後到期
.WithTenantId(目錄識別碼)
.Build();
// The permission scope required for EWS access
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
//Make the token request
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
var ews = new ExchangeService();
ews.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ews.Credentials = new OAuthCredentials(authResult.AccessToken);
//Impersonate the mailbox you'd like to access.
ews.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "xxx@www.xxx");

使用 ews 寄信 (exchange online 不支援 smtpclient)

var mms = new EmailMessage(ews);
mms.ToRecipients.Add(new EmailAddress("xxx@www.xxx"));
mms.CcRecipients.Add(new EmailAddress("xxx@www.xxx"));
mms.BccRecipients.Add(new EmailAddress("xxx@www.xxx"));
mms.Subject = "xxx";    
mms.Body = new MessageBody(BodyType.HTML, "xxx");
mms.Attachments.AddFileAttachment("xxx.xxx",stream);
mms.Send(); // 不會留信件在寄件備份

2020年5月11日 星期一

設定div 填滿可用空間,內容不足則出現捲軸

.directive('divwh', function ($timeout) {
        return {
            link: function (scope, elem, attrs) {
                var positioner = function () {
                    var h = $(window).height() - $(elem).offset().top - 5; // 使用最多高度 ,5px 緩衝(考慮捲軸空間)     
                    var w = $(window).width() - 190 - 10;   // 使用最多寬度,左邊預留190px,10px 緩衝(考慮捲軸空間)
                    $(elem).height(h);
                    $(elem).width(w);
                }
                $(window).resize(function () {
                    positioner();
                });
                $timeout(function () {
                    positioner();
                });
            }
        };
    });

2020年5月7日 星期四

table凍結欄跟列

假設凍結第一列及前三欄

css
====
 div.divunfinish {
  overflow: auto;height:300px; /* 非必要 */
}
     div.divunfinish   thead td {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;background-color:Brown;
}
div.divunfinish thead td:nth-child(1) {
  left: 0;
  z-index: 1;
}
div.divunfinish thead td:nth-child(2) {
  left: 40px;
  z-index: 1;
}
div.divunfinish thead td:nth-child(3) {
  left: 100px;
  z-index: 1;
}
div.divunfinish tbody td:nth-child(1) {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;background-color:white;
}
div.divunfinish tbody td:nth-child(2) {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 40px;background-color:white;
}
div.divunfinish tbody td:nth-child(3) {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 100px;background-color:white;
}

html
====
<div class="divunfinish">
<table style="width: 1530px;" >
<thead>
<tr>
...
<tbody>
<tr>
...

※ bootstrapvue b-table 若有設定為 responsive 則會造成凍結失效

Entity Framework 建立新物件並儲存後馬上取得關聯資料

使用 CreateProxy 建立物件,不要直接 new var newmodel = _contextXXX.CreateProxy<yyy>(); ... _contextXXX.yyy.Add(newmodel); await _contextXXX.SaveC...