2021年3月2日 星期二

Serial Log - Write to AWS Setting

            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月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] &#xd;&#xa;     ([controller] ,[action] ,[request] ,[response] ,[createtime] ,[issuccess] ,[requestid] ,[exceptionresult],[errorcode],[stringkeyword],[intkeyword],[guidkeyword]) &#xd;&#xa;     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

C# 要連接Oracle 有幾種方法
目前最推薦的就是利用 Oracle.ManagedDataAccess
但是此套件不支援舊版

所以要連接較舊版本的Oracle可以利用 
Oracle.DataAccess.dll


開發工具: Microsoft Visual Studio 2019
資料庫: Oracle9i

1.到Oracle 官網安裝 (以下有傳送門)

ODAC 11.2 Release 5 and Oracle Developer Tools for Visual Studio (11.2.0.3.20)

要注意版本,如果下載到新版(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# 比較字串不分大小寫

除了把字串ToUpper() 或 ToLower() 以外

還可以用 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的三大理由

  1. 加快開發速率
  2. 簡單、好用、易學習
  3. 加強自己對Html和CSS的結構學習,讓前端程式不再凌亂

基本語法介紹

  • 凡要使用Emmet 下完語法 按TAB鍵

  • 用 ‘>’ 串接 html 的層級

  • 用 ‘+’ 串接同階層

  • 打Emmet不要Key空白鍵

  • html tag 直接輸入關鍵字,不用輸入’<‘ 和 ‘>’

進階語法與實例

  1. 新增html 5 的檔案: html:5 (按Tab)
    EMMET1

  2. 創建html 架構 範例

div>h1+div#main>div.site>nav>ul#Item>(li.item$>span{this is my item})*5

Emmet03

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

EMMET03

語法 說明
# Tag 加入id
. Tag 加入class
$ 自動編碼 1,2,3 依序如下,如果想要二位數編碼01,02,03 可寫成‘$$’
*N 產生N個Tag
{} Tag加入描述內容
[] 加入屬性

補充說明:

如果想要預設起始值,可以使用’@‘

div.mydiv$@3*2

產生兩個div class各為mydiv3, mydiv4

EMMET05

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

EMMET06

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.com

2016年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月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 輪播

記錄一下 好用的輪播套件 slick 連結

然後下面範例是拿其他教學範例多加的功能

在特定的高度上會停止撥放幻燈片

     $(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

(不過為未來大概不會了 心已死)