Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.WithFunction("SystemUserName", () => Environment.UserName)
.Enrich.WithFunction("SystemName", () => sysetmName)
.Enrich.WithFunction("OSVersion", () => Environment.OSVersion.VersionString)
.Enrich.WithFunction("CurrentManagedThreadId", () => Environment.CurrentManagedThreadId.ToString())
.Enrich.WithFunction("CurrentTimeZone", () => TimeZone.CurrentTimeZone.StandardName)
// 時間戳
.Enrich.WithFunction("TimeStamp", () => {
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 當地時區
return ((long)(DateTime.Now - startTime).TotalSeconds).ToString(); // 相差秒數
})
.Enrich.WithFunction("LogGuid", () => Guid.NewGuid().ToString("N"))
.WriteTo.AmazonS3(
new JsonFormatter(),
"log.log",
"logforservice",
Amazon.RegionEndpoint.APNortheast1,
"KeyId",
"Key",
fileSizeLimitBytes: 10,
autoUploadEvents: true,
rollingInterval: Serilog.Sinks.AmazonS3.RollingInterval.Minute,
bucketPath: $"{sysetmName}/{DateTime.Now.Year}/{DateTime.Now.Month}/{DateTime.Now.Day}/{DateTime.Now.Hour}"
)
.CreateLogger();
2021年3月2日 星期二
Serial Log - Write to AWS Setting
2021年3月1日 星期一
NLOG Setting - write to Sql,File
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<variable name="myvar" value="myvalue"/>
<targets>
<target name="MessageLogFile" xsi:type="File" fileName="C://logs/CampaignFlow/SendMessageLog_${shortdate}.log"
layout="${longdate} | ${level:uppercase=true} | ${message} ${newline}" />
<target name="coloredConsole" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
layout="${longdate}|${pad:padding=5:inner=${level:uppercase=true}}|${message}" >
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
</target>
<target name="tracelogguid" xsi:type="database" connectionstring="${dbconnectionstring}" commandtext="insert into [dbo].[tracelog] 
 ([controller] ,[action] ,[request] ,[response] ,[createtime] ,[issuccess] ,[requestid] ,[exceptionresult],[errorcode],[stringkeyword],[intkeyword],[guidkeyword]) 
 values (@controller, @action, @request, @response, @createtime, @issuccess, @requestid, @exceptionresult,@errorcode,@stringkeyword,@intkeyword,@guidkeyword);">
<parameter name="@controller" layout="${event-properties:item=controller}" />
<parameter name="@action" layout="${event-properties:item=action}" />
<parameter name="@request" layout="${event-properties:item=request}" />
<parameter name="@response" layout="${event-properties:item=response}" />
<parameter name="@createtime" layout="${event-properties:item=createtime}" />
<parameter name="@issuccess" layout="${event-properties:item=issuccess}" />
<parameter name="@requestid" layout="${event-properties:item=requestid}" />
<parameter name="@request" layout="${event-properties:item=request}" />
<parameter name="@errorcode" layout="${event-properties:item=errorcode}" />
<parameter name="@exceptionresult" layout="${exception:tostring}" />
<parameter name="@stringkeyword" layout="${event-properties:item=stringkeyword}" />
<parameter name="@intkeyword" layout="${event-properties:item=intkeyword}" />
<parameter name="@guidkeyword" layout="${event-properties:item=guidkeyword}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="tracelogguid" />
<logger name="*" levels="Trace,Debug,Warn" writeTo="MessageLogFile,coloredConsole" />
</rules>
</nlog>
2020年5月27日 星期三
[ODA.NET] C# Connect Oracle 9i
目前最推薦的就是利用 Oracle.ManagedDataAccess
但是此套件不支援舊版
所以要連接較舊版本的Oracle可以利用 Oracle.DataAccess.dll
開發工具: Microsoft Visual Studio 2019
資料庫: Oracle9i
1.到Oracle 官網安裝 (以下有傳送門)
要注意版本,如果下載到新版(12.X)會不能用
安裝完成到安裝的資料夾下~\product\11.2.0\client_1\odp.net\bin\4 取出Oracle.DataAccess.dll
再加入專案就完成了

static void Main(string[] args)
{
string connstring =
"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=xxxx)(PORT=xxxx))" +
"(CONNECT_DATA=(SERVICE_NAME=xxxx)));User Id=xxxx;Password=xxxx;";
using (OracleConnection conn = new OracleConnection(connstring))
{
conn.Open();
string sql = "select * from xxxx where ROWNUM = 1";
using (OracleCommand comm = new OracleCommand(sql, conn))
{
using (OracleDataReader rdr = comm.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr.GetString(0));
}
}
}
}
}
參考:
C#連Oracle連線字串
Oracle ODAC with Oracle Developer Tools for Visual Studio
2019年11月29日 星期五
[C#] Lambda All() check ListA all in ListB
public static bool ContainsAll<T>(IEnumerable<T> source, IEnumerable<T> values)
{
return values.All(value => source.Contains(value));
}
2019年11月26日 星期二
新增 net core project
$ dotnet new web -o <專案名稱>
dotnet help 可以查看專案型態的參數
安裝npm $ npm install 檢查npm安裝版本
$ npm -v
init npm
$npm init
如果沒有要設定專案資訊 直接Enter到底
結束之後 會再package.json寫入設定
npm安裝套件 ex jquery
$ npm install jquery
安裝LibMan
$ dotnet tool install -g Microsoft.Web.LibraryManager.Cli
Run
$ dotnet run
Ref microsoft microsoft-SingleR install
2019年11月24日 星期日
.Net Core Console使用依賴注入
public static async Task Main(string[] args)
{
// 取得設定檔
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
// 建立容器
var serviceCollection = new ServiceCollection();
// 註冊服務
serviceCollection.AddTransient();
serviceCollection.AddTransient();
// 加入SqlServer 連線字串
serviceCollection.AddDbContext(options => options.UseSqlServer(config["ConnectionStrings:DefaultConnection"]));
// 建立依賴服務提供者
var serviceProvider = serviceCollection.BuildServiceProvider();
// 執行
await serviceProvider.GetRequiredService().Run();
}
C# 比較字串不分大小寫
還可以用 String.Compare()
//最後一個參數改成true 就可以忽略大小寫 String.Compare(strSource, strTarget, true)回傳為0 即相等
而另外一種我最常用來做搜尋的方法是Contains()
sourceString.Contains("Search-Word", StringComparison.InvariantCultureIgnoreCase,
new System.Globalization.CultureInfo("en-US")));
2019年3月4日 星期一
移除警告
如果要讓警告消失,用NotePad++ 開啟專案檔編輯,
加入 <DependsOnNETStandard>true</DependsOnNETStandard>
這樣一來 警告就不會再出現了
2018年12月4日 星期二
[SQL] 複製資料結構
複製資料結構
Select * into NewTable From OldTable Where 1=0
複製TABLE資料結構和資料
Select * into NewTable From OldTable
2018年3月15日 星期四
Emmet(一)
這是一款強大的前端開發工具,早期設計Html、CSS總是要手刻畫面,這套軟件大大幫助前端設計師提升開發速度
建議可搭配Sublime、Visual Studio Code等
前言
具有CSS和Html網頁基礎
為什麼要學習Emmet的三大理由
- 加快開發速率
- 簡單、好用、易學習
- 加強自己對Html和CSS的結構學習,讓前端程式不再凌亂
基本語法介紹
凡要使用Emmet 下完語法 按TAB鍵
用 ‘>’ 串接 html 的層級
用 ‘+’ 串接同階層
打Emmet不要Key空白鍵
html tag 直接輸入關鍵字,不用輸入’<‘ 和 ‘>’
進階語法與實例
新增html 5 的檔案: html:5 (按Tab)
創建html 架構 範例
div>h1+div#main>div.site>nav>ul#Item>(li.item$>span{this is my item})*5

這一串看起來很複雜嗎?
不要緊張 很簡單的!
讓我們看下圖,顯示結果

| 語法 | 說明 |
|---|---|
| # | Tag 加入id |
| . | Tag 加入class |
| $ | 自動編碼 1,2,3 依序如下,如果想要二位數編碼01,02,03 可寫成‘$$’ |
| *N | 產生N個Tag |
| {} | Tag加入描述內容 |
| [] | 加入屬性 |
補充說明:
如果想要預設起始值,可以使用’@‘
div.mydiv$@3*2
產生兩個div class各為mydiv3, mydiv4

若想要在Tag加入屬性,可以參考下圖

2016年12月26日 星期一
[IOS] Progress View
@IBOutlet weak var btnStart: UIButton!
@IBOutlet weak var progress: UIProgressView!
@IBOutlet weak var labelMsg: UILabel!
//計時器
var timer: Timer?
//計數
var count : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
progress.frame.size.width = 250
//可以自訂progress顏色
progress.progressTintColor = UIColor.red
progress.trackTintColor = UIColor.darkGray
progress.progress = 0
}
@IBAction func donloadClick(_ sender: UIButton) {
//按鈕失效 避免重複點擊
btnStart.isEnabled = false
count = 0
//參數順序亂掉會報錯
//The runTimedCode selector means that the timer will call a method named runTimedCode() every 0.5 seconds until the timer is terminated
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector:#selector(runTimedCode), userInfo: nil, repeats: true)
}
func runTimedCode() {
progress.progress = Float(count) / 100
labelMsg.text = "process: \(count)%"
count += 1
if count > 100 {
timer!.invalidate() // stop
timer = nil
btnStart.isEnabled = true
}
}
參考資料:hackingwithswift.com2016年12月15日 星期四
[IOS] ImageView 翻圖片
裡面有用到兩種不同Array寫法來存圖片
class ViewController: UIViewController {
@IBOutlet weak var btnPre: UIButton!
@IBOutlet weak var btnNext: UIButton!
@IBOutlet weak var labelName: UILabel!
@IBOutlet weak var image: UIImageView!
//兩種array方法
var arrayImage = ["水上威尼斯","史特拉斯堡-2","科瑪", "新天鵝堡_繽紛","春露"]
var pic: [UIImage] = [
UIImage(named: "水上威尼斯")!,
UIImage(named: "史特拉斯堡-2")!,
UIImage(named: "科瑪")!,
UIImage(named: "新天鵝堡_繽紛")!,
UIImage(named: "春露")!
]
var current:Int = 0
var count:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
count = arrayImage.count
//image.image = UIImage(named: "水上威尼斯")
image.image = pic[0]
labelName.text = arrayImage[0]
}
@IBAction func preClick(_ sender: UIButton) {
current -= 1
if current < 0 {
current = count - 1
}
//image.image = UIImage(named:String(arrayImage[current]))
image.image = pic[current]
labelName.text = arrayImage[current]
}
@IBAction func nextClick(_ sender: UIButton) {
current += 1
if current == count {
current = 0
}
//image.image = UIImage(named:String(arrayImage[current]))
image.image = pic[current]
labelName.text = arrayImage[current]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
[IOS] 自訂生成按鈕(CustomButton)
範例是在書上看到的,不過程式碼我有改過,因為Swift 3 出來了,而市面書上的範例程式碼... 你懂的
這篇主要是講後端生成程式碼 以Button為例
yourButtonName.addTarget(self, action:#selector(functionName(sender:)), for: .touchUpInside)
fun functionName(sender:UIButton) {
//....
}
action 這邊 如果沒有回傳值 (sender:) 就不用加了
View 的截圖 自訂12個按鈕
Controller全部程式碼
class ViewController: UIViewController {
@IBOutlet weak var labelTel: UITextField!
@IBOutlet weak var labelMsg: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...11 {
let x:Int = 100 + (i % 4) * 60
let y:Int = 140 + (i / 4) * 60
let buttonNumber:UIButton = UIButton(type: UIButtonType.system) as UIButton
//按鈕位置 大小
buttonNumber.frame = CGRect(x: x,y: y,width: 40, height: 35)
//文字顏色
buttonNumber.setTitleColor(UIColor.white, for: UIControlState.normal)
//按鈕背景
buttonNumber.backgroundColor = UIColor.black
//字型大小
buttonNumber.titleLabel?.font = UIFont(name: "System", size: 22.0)
if i == 10 {
buttonNumber.setTitle("X", for: UIControlState.normal)
//加入事件 #selector(funcName(sender:)) 函數是有參數的
buttonNumber.addTarget(self, action:#selector(clearClick(sender:)), for: .touchUpInside)
} else if i == 11 {
buttonNumber.setTitle("OK", for: UIControlState.normal)
buttonNumber.addTarget(self, action:#selector(sureClick(sender:)), for: UIControlEvents.touchUpInside)
}else {
buttonNumber.setTitle("\(i)", for: UIControlState.normal)
buttonNumber.addTarget(self, action:#selector(numberClick(sender:)), for: UIControlEvents.touchUpInside)
}
//加入按鈕
view.addSubview(buttonNumber)
}
}
func sureClick(sender:UIButton) {
if labelTel.text?.lengthOfBytes(using: String.Encoding.utf8) == 10 {
labelMsg.text = "Call " + labelTel.text!
} else if labelTel.text == "" {
labelMsg.text = "Please enter your phone number."
} else if (labelTel.text?.lengthOfBytes(using: String.Encoding.utf8))! > 10{
labelMsg.text = "Error"
}
}
func clearClick(sender:UIButton){
labelTel.text = ""
labelMsg.text = ""
}
func numberClick(sender:UIButton) {
labelTel.text = labelTel.text! + sender.currentTitle!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
2016年10月11日 星期二
[IOS] Rotation & Scale
這是在網路上找的教學
照著做了N遍......有些小疏漏,錯了就重來再重來這樣
確保自己可以記住QQ
想說以後弄個桌遊APP出來的時後 可以不用這麼辛苦
總之 這算是為了往後的作品做的前期準備吧XD
2016年8月11日 星期四
2016年8月8日 星期一
[Chrome] Notification 通知視窗

window.addEventListener('load', function () {
//確認使用者是否允許跳窗,如果沒有,就跳窗取權限
if (window.Notification && Notification.permission !== "granted") {
Notification.requestPermission(function (status) {
if (Notification.permission !== status) {
Notification.permission = status;
}
});
}
function NotifyMsg() {
var option = {
tag: 'Notification',
body: '測試測試測試',
data: 'I am a data',
icon: '' //可以自訂ICON
}
var n = new Notification("Title", option);
setTimeout(n.close.bind(n), 5000);
console.log(n.data);
n.onclick = function (event) {
event.preventDefault(); // prevent the browser from focusing the Notification's tab
window.open('http://www.google.com.tw/', '_blank');
}
}
var button = document.getElementsByTagName('button')[0];
button.addEventListener('click', function () {
// If the user agreed to get notified
// Let's try to send ten notifications
if (window.Notification && Notification.permission === "granted") {
NotifyMsg();
}
// If the user hasn't told if he wants to be notified or not
// Note: because of Chrome, we are not sure the permission property
// is set, therefore it's unsafe to check for the "default" value.
else if (window.Notification && Notification.permission !== "denied") {
Notification.requestPermission(function (status) {
if (status === "granted") {
NotifyMsg();
}
// Otherwise, we can fallback to a regular modal alert
else {
alert("Hi!");
}
});
}
// If the user refuses to get notified
else {
// We can fallback to a regular modal alert
alert("Hi!");
}
});
});
參考資料: MDN
2016年8月3日 星期三
[JQuery] slideShow 輪播
然後下面範例是拿其他教學範例多加的功能
在特定的高度上會停止撥放幻燈片
$(document).ready(function (){
//window.scroll 抓取使用者滾輪高度..這裡自訂600
var stop = false;
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
if (scrollTop >= 600 ) {
console.log("stop" + scrollTop);
stop = true;
} else {
console.log("r" + scrollTop);
stop = false;
}
});
var num = 1;
var tNum = 5;
var duration = 2000;
console.log("A");
run();
$("#box").mouseover(function () { stopRun(); })
.mouseout(function () { run();})
for (var i = 1; i <= tNum; i++) {
document.getElementById("tab" + i).onclick = show;
document.getElementById("con" + i).style.display = "none";
}
document.getElementById("con1").style.display = "block";
document.getElementById("tab1").className = "now-tab";
//在 autoShow 判斷是否停止撥放
function autoShow() {
if (stop) return;
for (var i = 1; i <= tNum; i++) {
document.getElementById("con" + i).style.display = "none";
document.getElementById("tab" + i).className = "";
}
if (num < tNum) { num++; } else { num = 1; }
document.getElementById("con" + num).style.display = "block";
document.getElementById("tab" + num).className = "now-tab";
}
function show() {
num = this.id.substr(3) - 1;
autoShow();
}
function stopRun() { clearInterval(myInterval); }
function run() { myInterval = setInterval(autoShow, duration); }
});
來源:Flycan-輪播廣告 教學
2016年7月28日 星期四
[SQL] 暫存表 Temporary Tables
都是可以用到暫存表去解決的
偏偏以前從沒機會使用過(也沒聽過 XD)
感謝同事幫忙 >_<
狀況 1. 搜尋出來的資料量太大,EXCEL沒辦法全部貼上
---> 把資料撈進暫存表 再從暫存表下條件慢慢撈~~
狀況2. 依照EXCEL上的資料順序 去撈取資料, 再把撈到的資料貼到EXCEL上
---> 所以先把EXCEL的資料建表 order by 一些欄位 就可以了)
//狀況1
select email
into #tempMail
from member with(nolock)
where ..some conditions
SELECT * FROM #tempMail WHERE email LIKE 'A%' ORDER BY email
//狀況2
//暫存表的建法 是在table名稱前加上 #
create table #tmp_table (return_id nvarchar(30) , pid nvarchar(20))
//建完後insert資料
insert into #tmp_table(return_id ,pid) values('XXXXXX','YYYY')
[SQL] 依照 in 來排序
// 這裡是用 ,pid, 當作排序依據 charindex(exp1,exp2)會回傳exp1所在的位置,起始值是1
select pid,name
from temp
where pid in ('p004','p008','p435','p123','p056')
order by charindex(',' + cast(pid as varchar(10) + ',' , ',p004','p008','p435','p123','p056,' ))
//如果排序的對象有空白(不管空白是在字串前或後) 可以用 rtrim() 來Trim掉空白
select rtrim(pid),name
from temp
where pid in ('p004','p008','p435','p123','p056')
order by charindex(',' + rtrim(cast(pid as varchar(10)) + ',' , ',p004','p008','p435','p123','p056,' ))
reference:
rtrim()
charindex()
2016年7月25日 星期一
[Android] 連WebService 拋接資料 心得 [註:沒內容]
這次我想練習 android 去連 WebService 實作拋/接 資料(Json)的部分
首先,我寫了一隻WebService
然後 Android 的CODE 也準備好了....
登!登!登! 因為我是用 VS 的測試開發環境
所以根本連不上Q__Q
所以呢...我就看看別人怎麼寫就...放棄了 ORZ
最近跑去玩XCode了...
玩android弄得我有點心力交瘁
一下子跑出記憶體不足 當機
一下又因為我太菜 Android Studio有些問題要解好久
不然就是卡卡的
難過 傷心
如果有機會 我會再更新這個Tag





