<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1829213234333389814</id><updated>2026-06-19T14:34:54.169+08:00</updated><category term="碎碎念"/><category term="瘋遊戲"/><category term="生活記"/><category term="泡網路"/><category term="科技宅"/><category term="C#"/><category term="饕客遊"/><category term="亂亂拍"/><category term="League of Legends"/><category term="MMORPG"/><category term="ASP.NET"/><category term="Facebook"/><category term="單車行"/><category term="Web Game"/><category term="愛音樂"/><category term="JavaScript"/><category term="TroubleShooting"/><category term="送很大"/><category term="Survival Gear"/><category term="社會"/><category term="Molehill Empire"/><category term="OpenCv"/><category term="Moon"/><category term="Deep Learning"/><category term="日本行"/><category term="LINQ"/><category term="OpenCvSharp"/><category term="Rift"/><category term="Cassandra"/><category term="Python"/><category term="SQL"/><category term="Survival Knowledge"/><category term="jQuery"/><category term="小市民看市政"/><category term="敗家"/><category term="日文筆記"/><category term="日本"/><category term="給路人問嗎"/><category term="逐字"/><category term="benjemin"/><category term="nosql"/><category term="Diablo 3"/><category term="Kapi Regnum"/><category term="Node.js"/><category term="新聞終結者"/><category term="Entity Framework"/><category term="FFXIV"/><category term="MVC"/><category term="Machine Learning"/><category term="專訪"/><category term="隨便煮"/><category term=".NET 6"/><category term=".NET core"/><category term="AJAX"/><category term="Blogger Hack"/><category term="DIY"/><category term="Mortal Online"/><category term="One Day In Taipei"/><category term="PostgreSQL"/><category term="SSD"/><category term="Starcraft 2"/><category term="SubSonic"/><category term="Surf"/><category term="Ubuntu"/><category term="Visual Studio"/><category term="黃金十年"/><category term=".NET"/><category term="CNTK"/><category term="HTML 5"/><category term="Microsoft"/><category term="MongoDb"/><category term="Outdoor"/><category term="WPF"/><category term="YOLO"/><category term="pgpool"/><category term="關西"/><category term="ACM"/><category term="Alienware"/><category term="BestPractices"/><category term="C++"/><category term="Chrome"/><category term="Computer Vision"/><category term="Couchbase"/><category term="Custom"/><category term="Dragon Ball Online"/><category term="Dungeons and Dragons Online"/><category term="Electron"/><category term="EmguCv"/><category term="Enum"/><category term="Europe 1400"/><category term="ExpressVPN"/><category term="Face Detection"/><category term="Flex"/><category term="GW2"/><category term="HD2"/><category term="HMAC"/><category term="Health Equipment"/><category term="ILogger"/><category term="IRL"/><category term="JAVA"/><category term="Localization"/><category term="LogProvider"/><category term="Logger"/><category term="MSSQL"/><category term="Object Detection"/><category term="PowerShell"/><category term="Preview"/><category term="Prius Online"/><category term="RabbitMQ"/><category term="SHA"/><category term="SHA384"/><category term="SRT"/><category term="Shop Heroes"/><category term="Sikuli"/><category term="SilverLight"/><category term="Slony-i"/><category term="Stream"/><category term="Super Tycoons"/><category term="Swagger"/><category term="TensorFlow"/><category term="VPN"/><category term="VS2022"/><category term="WSL2"/><category term="Windows 10"/><category term="Windows 8"/><category term="XBLA"/><category term="analytics"/><category term="core"/><category term="example code"/><category term="i18n"/><category term="uBlock Origin"/><category term="い形容詞"/><category term="です"/><category term="な形容詞"/><category term="京都"/><category term="動詞"/><category term="台灣"/><category term="和平"/><category term="商店英雄"/><category term="富貴險中求"/><category term="戰爭"/><category term="科普教育不能等"/><category term="翻譯"/><category term="選前選後兩樣情"/><category term="長知識"/><title type='text'>after dusk, before dawn</title><subtitle type='html'>最近好像沒啥能期待的MMO....</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.died.tw/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://www.died.tw/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>982</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-3106044993431825590</id><published>2025-09-07T06:20:00.001+08:00</published><updated>2025-09-07T06:25:50.109+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="IRL"/><category scheme="http://www.blogger.com/atom/ns#" term="SRT"/><category scheme="http://www.blogger.com/atom/ns#" term="Stream"/><title type='text'>OBS self hosted IRL server setup guide</title><content type='html'>This guide focus on two point: free and simple. Therefore, it will not use an actual IRL server. Instead, we will use OBS as IRL server.&lt;div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLr0qDUNkRgTm5ORxsZ1d-jIhHRlWVl3PC1mz8rIshUfy2Gd6KsaflaW9tfL2DvtyRGepbWFaPvwbro3HGCPHoDRq2Vn0Jr1-H8ssnm2XKi7GWzUdygvCb9fPg-yowLSf63DdXlEM53qu4VvrzoKDytAK5yMke9IjqAO9GzR0ybsay74PBCsYGBt7rcaGF/s761/Untitled%20Diagram.drawio.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;251&quot; data-original-width=&quot;761&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLr0qDUNkRgTm5ORxsZ1d-jIhHRlWVl3PC1mz8rIshUfy2Gd6KsaflaW9tfL2DvtyRGepbWFaPvwbro3HGCPHoDRq2Vn0Jr1-H8ssnm2XKi7GWzUdygvCb9fPg-yowLSf63DdXlEM53qu4VvrzoKDytAK5yMke9IjqAO9GzR0ybsay74PBCsYGBt7rcaGF/s16000/Untitled%20Diagram.drawio.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;If you only use your phone for IRL streaming, this guide is perfect for you. It requires no extra equipment and uses SRT/HEVC/OBS to achieve better streaming quality like a paid IRL server.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;
  
&lt;/div&gt;&lt;a href=&quot;http://www.died.tw/2025/09/obs-self-hosted-irl-server-setup-guide.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/3106044993431825590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2025/09/obs-self-hosted-irl-server-setup-guide.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/3106044993431825590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/3106044993431825590'/><link rel='alternate' type='text/html' href='http://www.died.tw/2025/09/obs-self-hosted-irl-server-setup-guide.html' title='OBS self hosted IRL server setup guide'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLr0qDUNkRgTm5ORxsZ1d-jIhHRlWVl3PC1mz8rIshUfy2Gd6KsaflaW9tfL2DvtyRGepbWFaPvwbro3HGCPHoDRq2Vn0Jr1-H8ssnm2XKi7GWzUdygvCb9fPg-yowLSf63DdXlEM53qu4VvrzoKDytAK5yMke9IjqAO9GzR0ybsay74PBCsYGBt7rcaGF/s72-c/Untitled%20Diagram.drawio.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-625801528528947947</id><published>2025-07-25T03:05:00.008+08:00</published><updated>2025-07-25T03:27:14.616+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="uBlock Origin"/><title type='text'>How to enable uBlock Origin in Chrome v139 ?</title><content type='html'>&lt;style&gt;  .redline {    text-decoration: underline;    text-decoration-color: red;  }&lt;/style&gt;
&lt;a href=&quot;https://ibb.co/7NXfHTWB&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;1243&quot; src=&quot;https://i.ibb.co/4g7qcDTC/image.png&quot; width=&quot;965&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
In Chrome version 139, it forced uBlock Origin disable and recommend user remove it.
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is the step.&lt;/div&gt;
&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;Open &lt;code class=&quot;prettyprint prettyprinted&quot; style=&quot;color:ForestGreen&quot;&gt;chrome://flags/&lt;/code&gt; in chrome browser URL.&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;redline&quot;&gt;Enable&lt;/span&gt; &lt;code class=&quot;prettyprint prettyprinted&quot; style=&quot;color:ForestGreen&quot;&gt;Temporarily unexpire M137 flags&lt;/code&gt; and &lt;code class=&quot;prettyprint prettyprinted&quot; style=&quot;color:ForestGreen&quot;&gt;Temporarily unexpire M138 flags&lt;/code&gt; , then relaunch browser.&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;redline&quot;&gt;Enable&lt;/span&gt; &lt;code class=&quot;prettyprint prettyprinted&quot; style=&quot;color:ForestGreen&quot;&gt;Allow legacy extension manifest versions&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;span class=&quot;redline&quot;&gt;Disable&lt;/span&gt; following 3 options, then relaunch browser.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint prettyprinted&quot; style=&quot;color:ForestGreen&quot;&gt;&lt;code class=&quot;js&quot;&gt;        Extension Manifest V2 Deprecation Warning Stage
        Extension Manifest V2 Deprecation Disabled Stage
        Extension Manifest V2 Deprecation Unsupported Stage
&lt;/code&gt;&lt;/pre&gt;

&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After enable/disable, your uBlock Origin should be back, now you can backup all your settings.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;If you still confuse about which options should enable or disable, you can check the screenshot on top of this topic, follow it.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hope it can help you.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/625801528528947947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2025/07/how-to-enable-ublock-origin-in-chrome.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/625801528528947947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/625801528528947947'/><link rel='alternate' type='text/html' href='http://www.died.tw/2025/07/how-to-enable-ublock-origin-in-chrome.html' title='How to enable uBlock Origin in Chrome v139 ?'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-4326490162899821394</id><published>2023-11-19T04:02:00.001+08:00</published><updated>2023-11-19T04:35:52.781+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ExpressVPN"/><category scheme="http://www.blogger.com/atom/ns#" term="VPN"/><title type='text'>ExpressVPN STEAL my credit card info to renew subscription</title><content type='html'>&lt;p&gt;Yes, it is ExpressVPN, one of top VPN in the world.&lt;/p&gt;&lt;p&gt;And it ExpressVPN steal my card info to&amp;nbsp;renew subscription, let&#39;s see how it happen.&lt;/p&gt;&lt;p&gt;In short:&lt;br /&gt;1. 2022/8/18, I purchased 1 year + 3 months plan($99.95) with credit card, Subscription ID 948*&lt;/p&gt;&lt;p&gt;2. The credit card expired in 2023.&lt;/p&gt;&lt;p&gt;3. 2023/11/17, my ExpressVPN plan expired.&lt;/p&gt;&lt;p&gt;4. It&#39;s Black Friday time, I compared few VPNs, give ExpressVPN another try, use new credit card to purchase 1 year + 3 months plan($99.95) again,&amp;nbsp;Subscription ID 1039*&lt;/p&gt;&lt;p&gt;5. 2023/11/18, ExpressVPN use my new credit card info to renewing Subscription ID 948*, charged US$116.95.&lt;/p&gt;&lt;p&gt;I have to say, it was &lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;STEAL&lt;/span&gt;&lt;/b&gt;, &lt;b&gt;&lt;span style=&quot;color: #fcff01;&quot;&gt;ExpressVPN steal my credit card info that for new subscription to renew another subscription without asking&lt;/span&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;



&lt;p&gt;Ok let&#39;s see the detail.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/2TQTz9W.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;631&quot; data-original-width=&quot;1181&quot; height=&quot;631&quot; src=&quot;https://i.imgur.com/2TQTz9W.png&quot; width=&quot;1181&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;You can see, my first plan purchased at 2022/8/18, Subscription ID 948*.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And my credit card used for Subscription ID 948* was expired, ExpressVPN sent a email notice me, but I didn&#39;t renew card info because ExpressVPN increased the price.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/5rxIOTz.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;547&quot; data-original-width=&quot;566&quot; height=&quot;547&quot; src=&quot;https://i.imgur.com/5rxIOTz.png&quot; width=&quot;566&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;Time moved to 2023/11/17, my ExpressVPN goes offline, after check their web I know my plan was expired.&lt;/div&gt;&lt;div&gt;After doing some research, I decide give ExpressVPN another try, because I am lazy to uninstall and install new VPN software.&lt;/div&gt;&lt;div&gt;So I purchase the Black Friday deal, 1 year + 3 months plan for $99.95 with my new credit card,&amp;nbsp;Subscription ID 1039*.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next day, 2023/11/18, I received an email said my ExpressVPN has renewing.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/ePM09El.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;287&quot; data-original-width=&quot;650&quot; height=&quot;287&quot; src=&quot;https://i.imgur.com/ePM09El.png&quot; width=&quot;650&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;It was&amp;nbsp;weird, so I checked ExpressVPN&#39;s website to figure out what happed.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/njjJFC5.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;632&quot; data-original-width=&quot;1363&quot; height=&quot;632&quot; src=&quot;https://i.imgur.com/njjJFC5.png&quot; width=&quot;1363&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have two subscription ID, start with 948 (old one) and 1039(new one).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Subscription ID 948*&amp;nbsp; : expired at 2023/11/17, credit card expired so it can&#39;t renew.&lt;/div&gt;&lt;div&gt;Subscription ID 1039*: purchased at 2023/11/17 with new credit card.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next day, &lt;b&gt;&lt;span style=&quot;color: #fcff01;&quot;&gt;I guess ExpressVPN system detect I have a working credit card, so it renew my old subscription without asking, using the new credit card info&lt;/span&gt;&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Subscription ID 948*&amp;nbsp; : renew at 2023/11/18 with new credit card info.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That&#39;s why I will say &lt;span style=&quot;color: red;&quot;&gt;ExpressVPN steal my card info to renew&amp;nbsp;subscription&lt;/span&gt;, ExpressVPN using my credit card to process unauthorized payment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally, beware ExpressVPN didn&#39;t notice you they will store your credit card information, it only said &quot;Your payment information is fully protected.&quot;.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/tDxQoG0.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;643&quot; data-original-width=&quot;732&quot; height=&quot;643&quot; src=&quot;https://i.imgur.com/tDxQoG0.png&quot; width=&quot;732&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Yea, not even in their TOS, I checked ExpressVPN Terms of Service at 2023/11/19, it didn&#39;t mention it will store/save your credit card info.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ExpressVPN is not bad, speed is ok, response time sometimes better than without VPN, I can play LOL with ExpressVPN and have lower ping, but I can&#39;t trust a company who steal your credit card info.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had ask customer service to refund my 2 subscriptions, hope it working or I have to issue VISA for suspicious transactions.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/4326490162899821394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2023/11/expressvpn-steal-my-credit-card-info-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/4326490162899821394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/4326490162899821394'/><link rel='alternate' type='text/html' href='http://www.died.tw/2023/11/expressvpn-steal-my-credit-card-info-to.html' title='ExpressVPN STEAL my credit card info to renew subscription'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-7207965454446754934</id><published>2023-01-11T04:37:00.001+08:00</published><updated>2023-01-11T06:41:27.066+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="台灣"/><category scheme="http://www.blogger.com/atom/ns#" term="和平"/><category scheme="http://www.blogger.com/atom/ns#" term="戰爭"/><category scheme="http://www.blogger.com/atom/ns#" term="碎碎念"/><category scheme="http://www.blogger.com/atom/ns#" term="社會"/><title type='text'>台灣想要的是和平，不是戰爭</title><content type='html'>很久沒寫文章了，看到PTT上有篇標題叫做「[問卦] PTT投降仔都沒想過台灣打贏戰爭嗎？」，回了之後想說別浪費，就潤一下搬到blog來。&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;http://www.died.tw/2023/01/blog-post.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/7207965454446754934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2023/01/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/7207965454446754934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/7207965454446754934'/><link rel='alternate' type='text/html' href='http://www.died.tw/2023/01/blog-post.html' title='台灣想要的是和平，不是戰爭'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-3286770760510332841</id><published>2022-06-22T16:39:00.003+08:00</published><updated>2022-06-28T16:31:33.582+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term=".NET 6"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>[.NET 6] Custom Converter for System.Text.Json</title><content type='html'>Some people asked a question about custom converter for System.Text.Json on Facebook .NET group.&lt;br&gt;
He want user get the specific format from DateTimeOffset (not DateTime)&lt;br&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;csharp&quot;&gt;
DateTimeOffset.UtcNow.ToString(&amp;quot;yyyy-MM-dd HH:mm:ss.fffzzz&amp;quot;);
//&amp;quot;2022-06-22 06:28:55.207+00:00&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;
If using default converter, the result will follow ISO 8601 format&lt;br&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;csharp&quot;&gt;
return DateTimeOffset.UtcNow;
//&amp;quot;2022-06-22T05:55:57.4313761+00:00&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;
And the don&amp;#39;t want to use ToString() to achieve it everytime, so the best way is add the custom converter to JsonOptions&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2022/06/net-6-customconverter-for-systemtextjson.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/3286770760510332841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2022/06/net-6-customconverter-for-systemtextjson.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/3286770760510332841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/3286770760510332841'/><link rel='alternate' type='text/html' href='http://www.died.tw/2022/06/net-6-customconverter-for-systemtextjson.html' title='[.NET 6] Custom Converter for System.Text.Json'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-5366457099761640252</id><published>2022-01-03T18:51:00.002+08:00</published><updated>2022-01-03T18:51:52.405+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WSL2"/><title type='text'>WSL2 - Temporary failure in name resolution</title><content type='html'>WSL2 is good thing, but dunno why some bug it never fixed.&lt;br /&gt;
&lt;br /&gt;
If you are first time install WSL2 and reboot or something like it, it may become no internet connectivity and show error&lt;br /&gt;
&lt;blockquote&gt;Temporary failure in name resolution&lt;/blockquote&gt;
&lt;br /&gt;
To fix it, please follow this gitgub issue, &lt;a href=&quot;https://github.com/microsoft/WSL/issues/5256#issuecomment-666545999&quot; target=&quot;_blank&quot;&gt;JohnnyQuest1983&#39;s reply&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The steps can be simple like this&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt;set generateResolvConf=false in /etc/wsl.conf&lt;/li&gt;
  &lt;li&gt;set dns in /etc/resolv.conf&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;br /&gt;
then use exit or wsl --shutdown, reboot wsl, and it worked, the internet back.</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/5366457099761640252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2022/01/wsl2-temporary-failure-in-name.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/5366457099761640252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/5366457099761640252'/><link rel='alternate' type='text/html' href='http://www.died.tw/2022/01/wsl2-temporary-failure-in-name.html' title='WSL2 - Temporary failure in name resolution'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-8631326193967223452</id><published>2021-10-14T23:09:00.002+08:00</published><updated>2021-10-15T01:54:41.576+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET 6"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Custom"/><category scheme="http://www.blogger.com/atom/ns#" term="ILogger"/><category scheme="http://www.blogger.com/atom/ns#" term="Logger"/><category scheme="http://www.blogger.com/atom/ns#" term="LogProvider"/><category scheme="http://www.blogger.com/atom/ns#" term="RabbitMQ"/><title type='text'>[.NET 6] Implement custom LogProvider with RabbitMQ into ILogger</title><content type='html'>&lt;div&gt;&lt;p&gt;In .NET 6, ILogger is very easy to use, but on modern project, we will write log to somewhere else and use log viewer to read it. For example: sent log to &lt;a href=&quot;https://www.rabbitmq.com/&quot; target=&quot;_blank&quot;&gt;RabbitMQ&lt;/a&gt; and read on &lt;a href=&quot;https://www.elastic.co/elastic-stack/&quot; target=&quot;_blank&quot;&gt;Kibana&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;div&gt;&lt;p&gt;Here is a demo to show how to lmplement a custom logging provider with RabbitMQ into ILogger in .NET 6 RC1, basically same as this &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/core/extensions/custom-logging-provider&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; but with some modify.&lt;/p&gt;&lt;/div&gt;

&lt;div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #93c47d;&quot;&gt;Step 0 : Before Start&lt;/span&gt;&lt;/h3&gt;&lt;/div&gt;

&lt;div&gt;&lt;p&gt;In this demo we choose &lt;a href=&quot;https://www.nuget.org/packages/RabbitMQ.Client/&quot; target=&quot;_blank&quot;&gt;RabbitMQ.Client&lt;/a&gt; to communite with RabbitMQ, you can choose other client if you want, just install it from nuget, easy.&lt;/p&gt;&lt;/div&gt;

&lt;div&gt;&lt;p&gt;Another thing is RabbitMQ server, if you don&amp;#39;t have one, you can use docker to create one.&lt;/p&gt;&lt;/div&gt;
&lt;div&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;shell&quot;&gt;docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.9-management&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2021/10/net-6-implement-custom-logprovider-with.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/8631326193967223452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2021/10/net-6-implement-custom-logprovider-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8631326193967223452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8631326193967223452'/><link rel='alternate' type='text/html' href='http://www.died.tw/2021/10/net-6-implement-custom-logprovider-with.html' title='[.NET 6] Implement custom LogProvider with RabbitMQ into ILogger'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-1284521332979106490</id><published>2021-09-28T21:55:00.003+08:00</published><updated>2021-09-28T21:55:00.177+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term=".NET 6"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Preview"/><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio"/><category scheme="http://www.blogger.com/atom/ns#" term="VS2022"/><title type='text'>[.NET 6] System.StackOverflowException after upgrade VS2022 to Preview 4.1 from 3.1</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/9wZvOZp.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;160&quot; data-original-width=&quot;626&quot; src=&quot;https://i.imgur.com/9wZvOZp.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After upgrade VS2022 to Preview 4.1 from 3.1, my project throw StackOverflowException (after fix lots of reference error)&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;System.StackOverflowException
  HResult=0x800703E9
  Message=Exception of type &#39;System.StackOverflowException&#39; was thrown.

Stack overflow.
Repeat 2291 times:
--------------------------------
   at Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnChangeTokenFired()
   at Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration`1+&amp;lt;&amp;gt;c[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].&amp;lt;RegisterChangeTokenCallback&amp;gt;b__7_0(System.Object)
   at System.Threading.CancellationTokenSource.Invoke(System.Delegate, System.Object, System.Threading.CancellationTokenSource)
   at System.Threading.CancellationTokenSource.Register(System.Delegate, System.Object, System.Threading.SynchronizationContext, System.Threading.ExecutionContext)
   at System.Threading.CancellationToken.Register(System.Delegate, System.Object, Boolean, Boolean)
   at System.Threading.CancellationToken.Register(System.Action`1&amp;lt;System.Object&amp;gt;, System.Object)
   at Microsoft.Extensions.Configuration.ConfigurationReloadToken.RegisterChangeCallback(System.Action`1&amp;lt;System.Object&amp;gt;, System.Object)
   at Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].RegisterChangeTokenCallback(Microsoft.Extensions.Primitives.IChangeToken)
--------------------------------
   at Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnChangeTokenFired()
   at Microsoft.Extensions.Primitives.ChangeToken+ChangeTokenRegistration`1+&amp;lt;&amp;gt;c[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].&amp;lt;RegisterChangeTokenCallback&amp;gt;b__7_0(System.Object)
   at System.Threading.CancellationTokenSource.Invoke(System.Delegate, System.Object, System.Threading.CancellationTokenSource)
   at System.Threading.CancellationTokenSource+CallbackNode+&amp;lt;&amp;gt;c.&amp;lt;ExecuteCallback&amp;gt;b__9_0(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.CancellationTokenSource+CallbackNode.ExecuteCallback()
   at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean)
   at System.Threading.CancellationTokenSource.NotifyCancellation(Boolean)
   at System.Threading.CancellationTokenSource.Cancel()
   at Microsoft.Extensions.Configuration.ConfigurationManager.RaiseChanged()
   at Microsoft.Extensions.Configuration.ConfigurationManager.AddSource(Microsoft.Extensions.Configuration.IConfigurationSource)
   at Microsoft.Extensions.Configuration.ConfigurationManager.Microsoft.Extensions.Configuration.IConfigurationBuilder.Add(Microsoft.Extensions.Configuration.IConfigurationSource)
   at Microsoft.Extensions.Configuration.ChainedBuilderExtensions.AddConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder, Microsoft.Extensions.Configuration.IConfiguration, Boolean)
   at Microsoft.Extensions.Configuration.ChainedBuilderExtensions.AddConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder, Microsoft.Extensions.Configuration.IConfiguration)
   at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
   at Program.&amp;lt;Main&amp;gt;$(System.String[])&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;div&gt;I know post to MS&#39;s developer forum is useless, and VS2022 can&#39;t downgrade now, so the only way is try and error by myself.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Turn out, the stackoverflow exception cause by &lt;b&gt;Microsoft.Extensions.Configuration &lt;/b&gt;from this code:&lt;/div&gt;

&lt;div&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;builder.Services.AddSingleton&amp;lt;IConfiguration&amp;gt;(builder.Configuration);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;After more dig-in, I found the framework already called this on&amp;nbsp;&lt;a href=&quot;https://github.com/dotnet/aspnetcore/blob/59baa0d6f93022e87cc82faaf0433fe3513a38a9/src/Hosting/Hosting/src/WebHostBuilder.cs#L290&quot; target=&quot;_blank&quot;&gt;Hosting&lt;/a&gt;&amp;nbsp;, so maybe the&amp;nbsp;duplicate call cause the stackoverflow exception, but still not sure why it worked on VS2022 preview 3.1, not work on preview 4.1.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #93c47d;&quot;&gt;Solution&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Remove the line&lt;/div&gt;
&lt;div&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;services.AddSingleton&amp;lt;IConfiguration&amp;gt;(configuration);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;(or similar) on your Program.cs&lt;/div&gt;

</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/1284521332979106490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2021/09/net-6-systemstackoverflowexception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1284521332979106490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1284521332979106490'/><link rel='alternate' type='text/html' href='http://www.died.tw/2021/09/net-6-systemstackoverflowexception.html' title='[.NET 6] System.StackOverflowException after upgrade VS2022 to Preview 4.1 from 3.1'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-6585384572787744965</id><published>2021-09-22T21:13:00.003+08:00</published><updated>2021-09-22T21:13:00.222+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="example code"/><category scheme="http://www.blogger.com/atom/ns#" term="HMAC"/><category scheme="http://www.blogger.com/atom/ns#" term="JAVA"/><category scheme="http://www.blogger.com/atom/ns#" term="SHA"/><category scheme="http://www.blogger.com/atom/ns#" term="SHA384"/><title type='text'>[JAVA] HMAC SHA384 example code</title><content type='html'>It was a bit hard to find correct HMAC SHA384 code for JAVA, so here to share my example code, hope can save some time to try and error.

&lt;div&gt;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;java&quot;&gt;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;

public class SecureUtils {

private static String bytesToHex(final byte[] hash) {
    final StringBuffer hexString = new StringBuffer();
    for (int i = 0; i &amp;lt; hash.length; i++) {
        final String hex = Integer.toHexString(0xff &amp;amp; hash[i]);
        if (hex.length() == 1) {
            hexString.append(&#39;0&#39;);
        }
        hexString.append(hex);
    }
    return hexString.toString();
}

public static void main(String[] args) throws NoSuchAlgorithmException {
    final String nonce = &quot;test&quot;; //your key
    final String message = &quot;Password&quot;; //your plain txt
    SecretKeySpec signingKey = new SecretKeySpec(nonce.getBytes(),&quot;HmacSHA384&quot;);
    final Mac mac = Mac.getInstance(&quot;HmacSHA384&quot;);
    try{
        mac.init(signingKey);
        System.out.println(bytesToHex(mac.doFinal(message.getBytes())));
    }
        catch(Exception ex){    }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
  
You can test this example in &lt;a href=&quot;http://tpcg.io/KUN888&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Check result with &lt;a href=&quot;https://www.freeformatter.com/hmac-generator.html&quot; target=&quot;_blank&quot;&gt;online hmac generator&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Those code modify from&amp;nbsp;stackoverflow&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/questions/45927378/hmac-sha-384-in-java&quot; target=&quot;_blank&quot;&gt;HMAC SHA-384 in Java&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/6585384572787744965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2021/09/java-hmac-sha384-example-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/6585384572787744965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/6585384572787744965'/><link rel='alternate' type='text/html' href='http://www.died.tw/2021/09/java-hmac-sha384-example-code.html' title='[JAVA] HMAC SHA384 example code'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-2311209706605064451</id><published>2021-01-31T11:15:00.001+08:00</published><updated>2021-02-01T11:34:09.153+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Alienware"/><category scheme="http://www.blogger.com/atom/ns#" term="敗家"/><category scheme="http://www.blogger.com/atom/ns#" term="生活記"/><title type='text'> [敗家] Alienware m17 R3</title><content type='html'>&lt;blockquote class=&quot;imgur-embed-pub&quot; data-id=&quot;a/Lu9PmBI&quot; lang=&quot;en&quot;&gt;&lt;a href=&quot;//imgur.com/a/Lu9PmBI&quot;&gt;Alienware m17 R3&lt;/a&gt;&lt;/blockquote&gt;&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;//s.imgur.com/min/embed.js&quot;&gt;&lt;/script&gt;
&lt;br /&gt;
上一台筆電是2013年買的&lt;a href=&quot;https://www.died.tw/2012/10/alienware-m14x-r2.html&quot; target=&quot;_blank&quot;&gt;Alienware M14x R2&lt;/a&gt;，拿來寫code已經有點慢了，最近終於找了機會買了新筆電，17吋螢幕真的比較適用啊。&lt;br /&gt;
&lt;br /&gt;
不能免俗地附上配備表。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/SBtW1Zf.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;800&quot; data-original-width=&quot;792&quot; height=&quot;640&quot; src=&quot;https://i.imgur.com/SBtW1Zf.png&quot; width=&quot;634&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
順帶一提，這次順便買了外星人背包，裝17吋筆電剛好，還有些空間可以裝我需要的東西，相當不錯。&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/7z12hF0.jpeg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;800&quot; data-original-width=&quot;450&quot; height=&quot;800&quot; src=&quot;https://i.imgur.com/7z12hF0.jpeg&quot; width=&quot;450&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
這是2020/12月底買的，沒想到一忙就忘記貼文，直到現在。
</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/2311209706605064451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2021/01/alienware-m17-r3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/2311209706605064451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/2311209706605064451'/><link rel='alternate' type='text/html' href='http://www.died.tw/2021/01/alienware-m17-r3.html' title=' [敗家] Alienware m17 R3'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-4842752323030390416</id><published>2020-11-08T11:18:00.001+08:00</published><updated>2020-11-08T11:18:00.605+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET core"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="TroubleShooting"/><title type='text'>[.NET Core] 400 Bad Request / &#39;MS-ASPNETCORE-TOKEN&#39; does not match the expected pairing token</title><content type='html'>&lt;p&gt;At this time, I am testing an old code build by .NET Core 2.0, when I tring to send request to the service, I always got 400 Bad Request, but I can know the service got request because I am running debug mode, it shows request coming and exception happend.&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;Since I can&#39;t find out the error just by 400 bad request, I open &quot;Application Insights Search&quot; in Visual Studio and found this error.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/IYEY3HE.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;99&quot; data-original-width=&quot;769&quot; src=&quot;https://i.imgur.com/IYEY3HE.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;After some digging on stackoverflow, I found the error cause by a old version bug.&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;This question &quot;&lt;a href=&quot;https://stackoverflow.com/questions/38839034/cannot-debug-in-visual-studio-after-changing-the-port-number&quot; target=&quot;_blank&quot;&gt;Cannot debug in Visual Studio after changing the port number?&lt;/a&gt;&quot; &#39;s answer has good explain about this error.&lt;/p&gt;

&lt;blockquote&gt;You are getting this error message because Kestrel expected to run behind IIS, and received a direct request. And it noticed that because IIS was not there to inject the MS-ASPNETCORE-TOKEN header.
--Gerardo Grignoli&lt;/blockquote&gt;
&lt;br /&gt;
&lt;p&gt;Here have some options to solve the problem:&lt;/p&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
  &lt;li&gt; Call UseUrls() before UseIISIntegration()&amp;nbsp;&lt;/li&gt;
  &lt;li&gt; Use Kestrel to debug, not IIS Express&amp;nbsp;&lt;/li&gt;
  &lt;li&gt; Upgrade the framework&lt;/li&gt;&lt;/ol&gt;
&lt;br/&gt;
&lt;p&gt;
That&#39;s all,&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/4842752323030390416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2020/11/net-core-400-bad-request-ms-aspnetcore.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/4842752323030390416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/4842752323030390416'/><link rel='alternate' type='text/html' href='http://www.died.tw/2020/11/net-core-400-bad-request-ms-aspnetcore.html' title='[.NET Core] 400 Bad Request / &#39;MS-ASPNETCORE-TOKEN&#39; does not match the expected pairing token'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-6895575522587387061</id><published>2020-11-01T15:43:00.006+08:00</published><updated>2020-11-01T15:43:02.715+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET core"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Enum"/><category scheme="http://www.blogger.com/atom/ns#" term="i18n"/><category scheme="http://www.blogger.com/atom/ns#" term="Localization"/><title type='text'>[.NET core] Localization with Enumeration</title><content type='html'>In .NET core, doing i18n is more easy than .NET Framework in my opinions, just give appropriate setting, then you can easily assign i18n string to anyplace you want.&lt;br /&gt;&lt;br /&gt;
Let&#39;s see how it work.&lt;div&gt;&lt;br /&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;

1.Add resource file&amp;nbsp;&lt;/h4&gt;&lt;div&gt;Usually I will put my resource file in &lt;span style=&quot;color: #3d85c6;&quot;&gt;[Resources]&lt;/span&gt; folder, remember put cultureInfo name on resx file like this.&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9KmpqdJbuPXSDp9Yi5CQLP-TwEJZ8TRGGL3BZp24UmXzu-5vXPCSD4j2yWbMGWV4mah0jcN8iR78BO5Zi1zGLr5eFd0IziDXATjWgCOLsG1lfz3Te454HDQ5KymC5L-ZGfogndT-91Y4r/s212/68747470733a2f2f692e696d6775722e636f6d2f58525145624e612e706e67.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;114&quot; data-original-width=&quot;212&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9KmpqdJbuPXSDp9Yi5CQLP-TwEJZ8TRGGL3BZp24UmXzu-5vXPCSD4j2yWbMGWV4mah0jcN8iR78BO5Zi1zGLr5eFd0IziDXATjWgCOLsG1lfz3Te454HDQ5KymC5L-ZGfogndT-91Y4r/s0/68747470733a2f2f692e696d6775722e636f6d2f58525145624e612e706e67.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;h4 style=&quot;text-align: left;&quot;&gt;2.Setup Startup.cs&lt;/h4&gt;
Add following code (depending how many language you support) into your IServiceCollection &lt;br/&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;//set Support Cultures and default
services.Configure&lt;RequestLocalizationOptions&gt;(options =&gt;
{
    var supportedCultures = new[]{
        new CultureInfo(&quot;en-US&quot;),
        new CultureInfo(&quot;zh-TW&quot;),
        new CultureInfo(&quot;ja-JP&quot;)
    };
    options.DefaultRequestCulture = new RequestCulture(&quot;en-US&quot;);
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});
//set resource path
services.AddLocalization(options =&gt; options.ResourcesPath = &quot;Resources&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Make sure your ResourcesPath set to right path.&lt;br/&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;3.DI Localizer&lt;/h4&gt;
Since we are using .NET Core, so we need to DI our Localizer before we using it, for example if you are use it on a controller.&lt;br/&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;private readonly IStringLocalizer _localizer;
public YourController(IStringLocalizerFactory factory)
{
   _localizer = factory.Create(&quot;Message&quot;, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
The &quot;Message&quot; is my resource name, you can DI multi Localizer if you have not only one resource group.&lt;br/&gt;
&lt;br /&gt;&lt;br /&gt;

&lt;h4 style=&quot;text-align: left;&quot;&gt;4.Usage&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/Wwywfip.png&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;322&quot; data-original-width=&quot;358&quot; src=&quot;https://i.imgur.com/Wwywfip.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;
Here is the content of my resource, the usage for Localizer is easy, just use it like a dictionary.&lt;br/&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;var str = _localizer[&quot;Cool&quot;];
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;
If you wanna get a localization string for enum, it was easy too, for example your enum called &quot;WeatherSummary&quot;.&lt;br/&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;var str = _localizer[WeatherSummary.Cool.ToString()];
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
It was very simple, don&#39;t need add custom thing like LocalizedDescriptionAttribute for enum i18n in .NET Framework.&lt;br/&gt;

&lt;br/&gt;&lt;br/&gt;
You can check my demo code on github &lt;a href=&quot;https://github.com/died/.NET-Core-Localization-and-Enum&quot; target=&quot;_blank&quot;&gt;.NET-Core-Localization-and-Enum&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;

Hope you enjoy it.&lt;br/&gt;


</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/6895575522587387061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2020/11/net-core-localization-with-enumeration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/6895575522587387061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/6895575522587387061'/><link rel='alternate' type='text/html' href='http://www.died.tw/2020/11/net-core-localization-with-enumeration.html' title='[.NET core] Localization with Enumeration'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9KmpqdJbuPXSDp9Yi5CQLP-TwEJZ8TRGGL3BZp24UmXzu-5vXPCSD4j2yWbMGWV4mah0jcN8iR78BO5Zi1zGLr5eFd0IziDXATjWgCOLsG1lfz3Te454HDQ5KymC5L-ZGfogndT-91Y4r/s72-c/68747470733a2f2f692e696d6775722e636f6d2f58525145624e612e706e67.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-3695890334330478169</id><published>2020-10-25T18:04:00.001+08:00</published><updated>2020-10-25T18:04:00.301+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET core"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>[.NET core] System.NotSupportedException: The collection type &#39;System.Object&#39; on &#39;somewhere&#39; is not supported. </title><content type='html'>Somehow if you are using .NET core and return a object on controller, you might meet this exception.&lt;div&gt;&amp;nbsp; &amp;nbsp;&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;
  System.NotSupportedException: The collection type &#39;System.Object&#39; on &#39;somewhere.InnerResult.Data&#39; is not supported.
   at System.Text.Json.JsonPropertyInfoNotNullable`4.GetDictionaryKeyAndValueFromGenericDictionary(WriteStackFrame&amp;amp; writeStackFrame, String&amp;amp; key, Object&amp;amp; value)
   at System.Text.Json.JsonPropertyInfo.GetDictionaryKeyAndValue(WriteStackFrame&amp;amp; writeStackFrame, String&amp;amp; key, Object&amp;amp; value)
   at System.Text.Json.JsonSerializer.HandleDictionary(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack&amp;amp; state)
   at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack&amp;amp; state)
   at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
   at TestWeb.Controllers.AuthController.VerifyToken(String token, Int32 tp) in C:\repos\somewhere\TestWeb\Controllers\AuthController.cs:line 51&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;div&gt;In this project, I always return my custom result called InnerResult in API controller.&lt;/div&gt;

&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;    public class InnerResult
    {
        public bool Success { get; set; } = true;
        public int Code { get; set; }
        public string Message { get; set; }
        public dynamic Data { get; set; }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

&lt;div&gt;If the result json was this format, .NET core default can handle it.&lt;/div&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;{
    &quot;success&quot;: true,
    &quot;code&quot;: 0,
    &quot;message&quot;: null,
    &quot;data&quot;: &quot;vfu3MF5RFlQV9dWNQCFh6iRPNxeezFaV&quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

&lt;div&gt;but if some object in property, it will throw System.NotSupportedException&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;{
    &quot;success&quot;: true,
    &quot;code&quot;: 0,
    &quot;message&quot;: null,
    &quot;data&quot;: {
        &quot;name&quot;: &quot;Died&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

That&#39;s because in .NET core , they default using&amp;nbsp;&lt;a href=&quot;https://docs.microsoft.com/en-US/dotnet/api/system.text.json?view=netcore-3.1&quot;&gt;System.Text.Json&lt;/a&gt; to deal with json convert, but somehow it can&#39;t handle object in property, so......
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;To solve it, we can use our old friend&amp;nbsp;Json.NET to save the day. (actually, using &lt;a href=&quot;https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.NewtonsoftJson/&quot; target=&quot;_blank&quot;&gt;Microsoft.AspNetCore.Mvc.NewtonsoftJson&lt;/a&gt;)&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;blockquote&gt;&lt;div&gt;Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.1.9&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;If you are using .NET core 2.x , add&amp;nbsp;&lt;span class=&quot;pun&quot; style=&quot;box-sizing: border-box; color: #e8e6e3; font-family: Menlo, Monaco, Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 15px;&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;typ&quot; style=&quot;box-sizing: border-box; color: #5cbbd7; font-family: Menlo, Monaco, Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 15px;&quot;&gt;AddNewtonsoftJson&lt;/span&gt;&lt;span class=&quot;pun&quot; style=&quot;box-sizing: border-box; color: #e8e6e3; font-family: Menlo, Monaco, Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 15px;&quot;&gt;()&lt;/span&gt;&amp;nbsp;after your AddMVC()&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;services.AddMvc().AddNewtonsoftJson();&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If using .NET core 3.x , add it after what you have.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;services.AddControllers().AddNewtonsoftJson();&lt;br/&gt;
  services.AddControllersWithViews().AddNewtonsoftJson();&lt;br/&gt;
  services.AddRazorPages().AddNewtonsoftJson();&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Then no more this System.NotSupportedExceptio again.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/3695890334330478169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2020/10/net-core-systemnotsupportedexception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/3695890334330478169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/3695890334330478169'/><link rel='alternate' type='text/html' href='http://www.died.tw/2020/10/net-core-systemnotsupportedexception.html' title='[.NET core] System.NotSupportedException: The collection type &#39;System.Object&#39; on &#39;somewhere&#39; is not supported. '/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-5496276900037717096</id><published>2020-10-18T12:26:00.016+08:00</published><updated>2020-10-20T17:17:29.175+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="core"/><title type='text'>[.NET core] AddPolicy to Authorize on MVC controller</title><content type='html'>Sometimes when you are using C# identity, the [Authorize] attribute is not enough,for example, you want additional check not only claims or role, then you can try add policy to make it.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;In this example, we assume a part of method need check token in user claims before access, here is how to implement it.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;1.add a AuthorizationHandler for your policy&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;code&gt;&amp;nbsp;Handler/AuthorizeTokenHandler.cs&lt;/code&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;namespace Example.Handler
{
    // Custom AuthorizationHandler for check token in claim
    public class AuthorizeTokenHandler : AuthorizationHandler&amp;lt;TokenRequirement&amp;gt;
    {
        private readonly AuthService _auth;

        public AuthorizeTokenHandler(AuthService auth)
        {
            _auth = auth;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TokenRequirement requirement)
        {
            //no token claim
            if (!context.User.HasClaim(x =&amp;gt; x.Type == &quot;Token&quot;))
            {
                context.Fail();
                return Task.CompletedTask;
            }

            var username = context.User.FindFirst(ClaimTypes.Name).Value;
            var token = context.User.FindFirst(&quot;Token&quot;).Value;

            #region check token
            if (_auth.CheckToken(username,token))
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
            #endregion

            return Task.CompletedTask;
        }
    }

    public class TokenRequirement : IAuthorizationRequirement
    {
    }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;


&lt;div&gt;2. add to startup, in ConfigureServices&lt;/div&gt;&lt;br /&gt;

&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;            //handler
            services.AddSingleton&amp;lt;IAuthorizationHandler, AuthorizeTokenHandler&amp;gt;();
            
            //add policy
            services.AddAuthorization(options =&gt;
            {
                options.AddPolicy(&quot;TokenRequire&quot;, policy =&gt;
                    policy.Requirements.Add(new TokenRequirement()));
            });
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

&lt;div&gt;3. apply policy to Authorize when you need&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;[Authorize(Policy = &quot;TokenRequire&quot;)]
[HttpPost]
public ApiResult SomeMethod()
{
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

&lt;div&gt;That&#39;s all, enjoy it.&lt;/div&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/5496276900037717096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2020/10/c-core-addpolicy-to-authorize-on-mvc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/5496276900037717096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/5496276900037717096'/><link rel='alternate' type='text/html' href='http://www.died.tw/2020/10/c-core-addpolicy-to-authorize-on-mvc.html' title='[.NET core] AddPolicy to Authorize on MVC controller'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-4053172513380820429</id><published>2020-10-11T22:38:00.002+08:00</published><updated>2020-10-20T12:52:55.241+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="BestPractices"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>[C#] Best Practices of Get Claim from Identity</title><content type='html'>If you are using ASP.NET Identity, whatever using &lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-3.1&amp;amp;tabs=visual-studio&quot; target=&quot;_blank&quot;&gt;ASP.NET Core Identy&lt;/a&gt; or &lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity&quot; target=&quot;_blank&quot;&gt;ASP.NET Identity&lt;/a&gt;, usually you will add some claims into the identity and use it later, but I saw lot people using unsafe way to get claim value from identity, it may cause uncatch error if the claim type not exists, let&#39;s see the code.

&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;//set some claims first
var claims = new List&amp;lt;Claim&amp;gt;
{
     new Claim(ClaimTypes.Name,&quot;test name&quot;),
     new Claim(&quot;Token&quot;,&quot;token123&quot;),
     new Claim(&quot;Number&quot;,&quot;3&quot;)
     //new Claim(&quot;dummy&quot;,&quot;dummy string&quot;)
};
var ci = new ClaimsIdentity(claims);

//most seen way, throw error if not exists
var name = ci.Claims.First(x =&gt; x.Type == ClaimTypes.Name).Value;
var token = ci.Claims.First(x =&gt; x.Type == &quot;Token&quot;).Value;  
//using FirstOrDefault() only, throw error if not exists
//var dunno = ci.Claims.FirstOrDefault(x =&gt; x.Type == &quot;dunno&quot;).Value;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Using this way is easy, but if the claim not exists, if will cause error, whatever you are using First() or FirstOrDefault().

If want to using FirstOrDefault() to get claim value, you can using this fixed way.
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;
            //fixed FirstOrDefault way: return null if not exists
            var dunno = ci.Claims.Where(x =&gt; x.Type == &quot;dunno&quot;).Select(x =&gt; x.Value).FirstOrDefault();
            
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

but you can use &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity.hasclaim?view=netcore-3.1&quot; target=&quot;_blank&quot;&gt;HasClaim&lt;/a&gt; method to check claim exist first, and give a proper value if it not exists.
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;
            //safe way: using HasClaim to check
            var dummy = ci.HasClaim(x =&gt; x.Type == &quot;dummy&quot;)
                ? ci.Claims.First(x =&gt; x.Type == &quot;dummy&quot;).Value
                : null;
            
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

or you can choose this short way by using &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity.findfirst?view=netcore-3.1&quot; target=&quot;_blank&quot;&gt;FindFirst&lt;/a&gt; method.
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;
            //short way: using FindFirst
            var dummyShort = ci.FindFirst(&quot;dummy&quot;)?.Value;
            //short way for int
            int.TryParse(ci.FindFirst(&quot;Number&quot;)?.Value, out var number);
            
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;

I think use ClaimsIdentity.FindFirst Method is the best practices for get claim value.
&lt;br&gt;
You can test those here in &lt;a href=&quot;https://dotnetfiddle.net/g9UmI1&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; 
&lt;iframe width=&quot;100%&quot; height=&quot;600&quot; src=&quot;https://dotnetfiddle.net/Widget/g9UmI1&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/4053172513380820429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2020/10/c-best-practices-of-get-claim-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/4053172513380820429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/4053172513380820429'/><link rel='alternate' type='text/html' href='http://www.died.tw/2020/10/c-best-practices-of-get-claim-from.html' title='[C#] Best Practices of Get Claim from Identity'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-6540945254379586136</id><published>2020-06-02T20:29:00.000+08:00</published><updated>2020-06-02T20:35:52.408+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Survival Knowledge"/><title type='text'>幾個關於熊的謠言</title><content type='html'>最近在網路上發現有人對於熊有些錯誤觀點，這很可能造成真正遇到熊時的人員傷亡，所以找了一下資料，想來澄清一下這些謠言/迷思。&lt;br&gt;
&lt;br&gt;
以下資料來源翻譯自&lt;a href=&quot;https://yellowstonebearworld.com/&quot;&gt;Yellowstone Bear World&lt;/a&gt; &lt;br&gt;
&lt;br&gt;
&lt;h4&gt;謠言#1：熊的視力很差&lt;/h4&gt;&lt;a href=&quot;https://yellowstonebearworld.com/myth-1-bears-have-bad-eyesight&quot;&gt;Myth #1: Bears have bad eyesight&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
這確實是一個常見的錯誤認知。是的，熊確實有驚人的嗅覺，但牠的嗅覺並不是彌補視力的不足，實際上牠們具有很好的視力。 &lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://i.imgur.com/MiShtBZ.png&quot; data-original-width=&quot;300&quot; data-original-height=&quot;166&quot; alt=&quot;Bears actually have excellent eyesight.&quot; title=&quot;Bears actually have excellent eyesight.&quot;&gt;&lt;/div&gt;熊在白天的視力與人類相同，但是到了夜晚，牠們出色的視覺才顯出了作用。&lt;br&gt;
&lt;br&gt;
就像您家的狗或貓一樣，熊擁有出色的夜視能力。 牠們的眼睛後部有一個稱為脈絡膜層(Tapetum lucidum)的反射膜，該膜可反射光，並使光敏細胞對光進行第二次反應，從而極大地增強了他們在夜間的視力。 &lt;br&gt;
&lt;br&gt;
這就是為什麼如果您在晚上看到牠們的照片，牠們的眼睛看起來會發綠。&lt;br&gt;
&lt;br&gt;
因此，別被騙了...那些熊可能會在您見到牠們之前先見到您！ (有關資訊請參見Sylvia Dolson的&lt;a href=&quot;https://amzn.to/36WNQ3f&quot;&gt;《熊學 Bear-ology》&lt;/a&gt;)&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2020/06/blog-post.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/6540945254379586136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2020/06/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/6540945254379586136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/6540945254379586136'/><link rel='alternate' type='text/html' href='http://www.died.tw/2020/06/blog-post.html' title='幾個關於熊的謠言'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-1005503975819805751</id><published>2019-12-12T14:58:00.000+08:00</published><updated>2019-12-12T14:58:42.251+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="碎碎念"/><title type='text'>少女韓國瑜：環保少女 Greta Thunberg</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://i.imgur.com/OfEhXbk.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;800&quot; data-original-width=&quot;584&quot; src=&quot;https://i.imgur.com/OfEhXbk.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;br&gt;
今年Times的年度人物，是來自瑞典的環保少女Greta Thunberg，就先不說她不在投票前三名，得票不到4%是怎麼被操作選上的這種拉基事了，很多人都從媒體片面了解這個人，覺得她很環保很有知識很有行動力啥的，但其實大部分人都被騙了，她就是個少女韓國瑜而已。&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2019/12/greta-thunberg.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/1005503975819805751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2019/12/greta-thunberg.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1005503975819805751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1005503975819805751'/><link rel='alternate' type='text/html' href='http://www.died.tw/2019/12/greta-thunberg.html' title='少女韓國瑜：環保少女 Greta Thunberg'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/u9KxE4Kv9A8/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-61289326090651932</id><published>2019-01-10T13:17:00.000+08:00</published><updated>2019-01-10T13:17:15.999+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Deep Learning"/><category scheme="http://www.blogger.com/atom/ns#" term="OpenCvSharp"/><category scheme="http://www.blogger.com/atom/ns#" term="YOLO"/><title type='text'>[C#] YOLO3 with OpenCvSharp4</title><content type='html'>&lt;img border=&quot;0&quot; data-original-height=&quot;950&quot; data-original-width=&quot;1600&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiUVTE2RX6NRDw2O8BTF7Mk-L2RWsnJDeTqy5J0x4S7FT-rx1aiRmFC9NFyfxYuu2hYq7XkqlEsndMe38G8hAtiaZglI9F80CF-To_Po2-kLbPn0pnAhc11CExIteyuwge5NTgIlf-h71V/s1600/Yolo3_Logo.png&quot; width=&quot;100%&quot;&gt;&lt;br&gt;
&lt;br&gt;
One year ago, I writed &lt;a href=&quot;https://www.died.tw/2018/01/c-opencvsharp-dnn-with-yolo2.html&quot;&gt;[C#] OpenCvSharp DNN with YOLO2&lt;/a&gt;, since YOLO3 come out for a while and OpenCV released version 4 on Dec 2018, I think it&amp;#39;s time to make a upgrade.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2019/01/c-yolo3-with-opencvsharp4.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/61289326090651932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2019/01/c-yolo3-with-opencvsharp4.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/61289326090651932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/61289326090651932'/><link rel='alternate' type='text/html' href='http://www.died.tw/2019/01/c-yolo3-with-opencvsharp4.html' title='[C#] YOLO3 with OpenCvSharp4'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiUVTE2RX6NRDw2O8BTF7Mk-L2RWsnJDeTqy5J0x4S7FT-rx1aiRmFC9NFyfxYuu2hYq7XkqlEsndMe38G8hAtiaZglI9F80CF-To_Po2-kLbPn0pnAhc11CExIteyuwge5NTgIlf-h71V/s72-c/Yolo3_Logo.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-8451653627403039952</id><published>2018-11-21T11:24:00.000+08:00</published><updated>2018-11-21T15:41:15.844+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Swagger"/><title type='text'>[C#] Swashbuckle WebAPI HTTPS BaseUrl and Bearer token </title><content type='html'>因為&lt;a href=&quot;https://github.com/domaindrivendev/Swashbuckle&quot;&gt;Swashbuckle&lt;/a&gt;作者跑去專心做Swashbuckle.AspNetCore了，所以在使用上遇到一些問題時要自己想辦法解，這邊紀錄一下遇到的兩個問題。&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;h4&gt;HTTPS BaseUrl Issue&lt;/h4&gt;因為我有用 cloudflare 的 Flexible SSL，在production環境上外面看起來是HTTPS，但Server上走的仍然是HTTP，這時候swagger的 BaseUrl 會因為 Uri Scheme 出問題，所以要來想辦法解，整理需求後，我只需要本機測試(localhost)走HTTP，其他就走HTTPS，按照這個需求來做的解法如下。&lt;br&gt;
&lt;br&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;//SwaggerConfig.cs
config.EnableSwagger(c =&amp;gt;
{
    c.RootUrl(ResolveBasePath);
    c.Schemes(new[] { &amp;quot;http&amp;quot;, &amp;quot;https&amp;quot; });
}

internal static string ResolveBasePath(HttpRequestMessage message)
{
    //fix for Cloudflare Flexible SSL and localhost test
    var scheme = message.RequestUri.Host.IndexOf(&amp;quot;localhost&amp;quot;) &amp;gt; -1 ? &amp;quot;http://&amp;quot; : &amp;quot;https://&amp;quot;;
    return scheme + message.RequestUri.Authority;
}
&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;
這樣就可以兼顧正式機與本機開發都正常使用，如果透過proxy那要再另外解，我這邊就先略過。&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2018/11/c-swashbuckle-webapi-https-baseurl-and.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/8451653627403039952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/11/c-swashbuckle-webapi-https-baseurl-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8451653627403039952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8451653627403039952'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/11/c-swashbuckle-webapi-https-baseurl-and.html' title='[C#] Swashbuckle WebAPI HTTPS BaseUrl and Bearer token '/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-8016352892256482056</id><published>2018-10-24T15:42:00.000+08:00</published><updated>2018-10-24T15:42:56.936+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>[ASP.NET MVC] Remove response header | 移除回應標頭 </title><content type='html'>&lt;br /&gt;
有時候做網站會想把一些header移除，但是久久做一次都要查一下，所以決定寫這篇之後就不用查了。&lt;br /&gt;
&lt;br /&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;207&quot; data-original-width=&quot;531&quot; src=&quot;https://i.imgur.com/XSCv8Kd.png&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
目前使用的版本是MVC 5.2.4，跑在IIS 10上，上面可以看到沒設定前，response有三個header是一般來說大家會去移除的，分別是server, x-aspnet-version, x-powered-by，下面分別說一下移除方法，我是找不用動到IIS設定，改動最小的做法，但是需要改到web.config，如果權限不能碰到web.config的話要另外想辦法。&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;Server&lt;/span&gt;&lt;/h4&gt;移除Server header需要在 Global.asax.cs 裡面加上這段&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;code class=&quot;cs&quot;&gt;        protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
        {
            var app = sender as HttpApplication;
            // remove Server header
            app?.Context.Response.Headers.Remove(&quot;Server&quot;);
        }
&lt;/code&gt;&lt;/pre&gt;不過這樣子只能移除由程式產生檔案的header，對於靜態檔像是.js .css之類的還是會有header，所以還有另外一個地方要修改；在web.config內的system.webServer元素內，將 modules 加入runAllManagedModulesForAllRequests=&quot;true&quot;這個設定，像是下面這樣，就可以把靜態檔的header也移掉。&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;https://i.imgur.com/OWZ8aA9.png&quot; data-original-width=&quot;529&quot; data-original-height=&quot;54&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;X-AspNet-Version&lt;/span&gt;&lt;/h4&gt;要移除這個header要修改web.config，在httpRuntime element內加入enableVersionHeader=&quot;false&quot;，像我的情況就是下面這樣。&lt;br /&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;193&quot; data-original-width=&quot;652&quot; src=&quot;https://i.imgur.com/12xZc5W.png&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;X-Powered-By&lt;/span&gt;&lt;/h4&gt;這header也要在web.config內修改，在system.webServer元素內加入customHeaders，像是下面這樣&lt;br /&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;214&quot; data-original-width=&quot;359&quot; src=&quot;https://i.imgur.com/XaSEIa8.png&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
最後再看看結果，上面三個header都移除了，可賀可喜，收工。&lt;br /&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;163&quot; data-original-width=&quot;409&quot; src=&quot;https://i.imgur.com/HhtG84T.png&quot; /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/8016352892256482056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/10/aspnet-mvc-remove-response-header.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8016352892256482056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8016352892256482056'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/10/aspnet-mvc-remove-response-header.html' title='[ASP.NET MVC] Remove response header | 移除回應標頭 '/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-5142039111612223996</id><published>2018-10-23T13:25:00.000+08:00</published><updated>2018-10-24T11:24:54.663+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>[C#] XML to Object / Generic | XML泛型轉換</title><content type='html'>Recently, I have to some things related to XML in the work, so I prepared some tools and wrote the method of converting XML to Object, but it is not very beautiful on using.&lt;br&gt;
最近工作上需要做一些跟XML有關的東西，所以先準備些工具，一開始也沒多想就寫了將XML轉成Object的方法，但是使用上有點不漂亮。&lt;br&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size:12px&quot;&gt;&lt;code class=&quot;cs&quot;&gt;static object XmlToObj(XDocument xml, Type objType)
{
    object obj;
    try
    {
        XmlSerializer serializer = new XmlSerializer(objType);
        using (TextReader reader = new StringReader(xml.ToString()))
        {
            obj = serializer.Deserialize(reader);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
    return obj;
}
&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;
Using above XmlToObj, it need to cast it first, the code isn&amp;#39;t feel so beauty, so I decide rewrite it to generic method.&lt;br&gt;
使用上面的XmlToObj，會需要做轉型才能使用，code感覺不是很美，所以我決定改寫成泛型的方式。&lt;br&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;font-size:12px&quot;&gt;&lt;code class=&quot;cs&quot;&gt;var result = (PurchaseOrder)XmlToObj(doc, typeof(PurchaseOrder));
&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2018/10/c-xml-to-object-generic-xml.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/5142039111612223996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/10/c-xml-to-object-generic-xml.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/5142039111612223996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/5142039111612223996'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/10/c-xml-to-object-generic-xml.html' title='[C#] XML to Object / Generic | XML泛型轉換'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-1659352170469071150</id><published>2018-06-06T16:51:00.000+08:00</published><updated>2018-06-06T17:00:32.537+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Entity Framework"/><category scheme="http://www.blogger.com/atom/ns#" term="LINQ"/><title type='text'>[C#] Implement Pivot with LINQ | 用 LINQ 實現 Pivot</title><content type='html'>Here we will demo how to using LINQ implement Pivot feature in two ways, at first we need a demo data source.&lt;br&gt;
這邊我們要展示如何使用LINQ實作Pivot功能，共兩個方式，首先我們需要一個示範的資料來源。&lt;br&gt;
&lt;br&gt;
&lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://www.flickr.com/photos/doomdied/42561632362/in/dateposted-public/&quot; title=&quot;pivot_1&quot;&gt;&lt;img alt=&quot;pivot_1&quot; height=&quot;659&quot; src=&quot;https://farm2.staticflickr.com/1747/42561632362_8ea3c4aba1_o.png&quot; width=&quot;306&quot;&gt;&lt;/a&gt;&lt;br&gt;
That table with two brand(both having two products)in four months will be use in this demo.&lt;br&gt;
這個有兩個品牌(各有兩個產品)在四個月間的表格將會用在這次demo.&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2018/06/c-implement-pivot-with-linq-linq-pivot.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/1659352170469071150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/06/c-implement-pivot-with-linq-linq-pivot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1659352170469071150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1659352170469071150'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/06/c-implement-pivot-with-linq-linq-pivot.html' title='[C#] Implement Pivot with LINQ | 用 LINQ 實現 Pivot'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-8621678328396223325</id><published>2018-05-25T15:11:00.002+08:00</published><updated>2018-05-25T15:13:21.807+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="小市民看市政"/><category scheme="http://www.blogger.com/atom/ns#" term="碎碎念"/><title type='text'>政府錯了，機車才是最乾淨的交通工具</title><content type='html'>&lt;span style=&quot;color: #666666; font-size: small;&quot;&gt;[At first，這邊所謂的交通工具，定義為使用燃油(汽油、柴油)的交通工具。]&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
五月中時，新任總統府祕書長陳菊表示「&lt;a href=&quot;http://www.cna.com.tw/news/aipl/201805160005-1.aspx&quot;&gt;新北市機車全台最多 汙染超過深澳電廠&lt;/a&gt;」，言下之意就是機車很汙染就對了。&lt;br&gt;
&lt;br&gt;
政府每次都拿最弱勢的機車開刀早就不意外了，之前當上行政院長的賴清德「&lt;a href=&quot;https://www.thenewslens.com/article/86022&quot;&gt;抗空汙&lt;/a&gt;」也是先砍機車再說，反正政府與論就是讓民眾覺得機車汙染很大，但事實真的是這樣嗎 ?&lt;br&gt;
&lt;br&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;錯，在汽油車、柴油車、機車三者中，機車是最乾淨的。&lt;/span&gt;&lt;/b&gt;&lt;br&gt;
&lt;br&gt;
以&lt;span style=&quot;color: yellow;&quot;&gt;平均單輛總排放&lt;/span&gt;來看，&lt;span style=&quot;color: yellow;&quot;&gt;機車不到汽油車的二分之一，更不到柴油車的十六分之一&lt;/span&gt;，若只看&lt;span style=&quot;color: yellow;&quot;&gt;PM2.5排放，單輛汽油車平均是機車的三倍，柴油車則是將近機車的七十八倍&lt;/span&gt;。&lt;br&gt;
&lt;iframe frameborder=&quot;0&quot; height=&quot;450.89916666666664&quot; scrolling=&quot;no&quot; seamless=&quot;&quot; src=&quot;https://docs.google.com/spreadsheets/d/e/2PACX-1vQFBoqcV_bW8vwOYH7s4pFtNhJZ9ZRUDjk1bnlWkpKU_UL3RuvCsnKbblGFIG8lhz9miajYI1DalK9s/pubchart?oid=5699429&amp;amp;format=interactive&quot; width=&quot;785.8457207207207&quot;&gt;&lt;/iframe&gt;&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2018/05/blog-post.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/8621678328396223325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/05/blog-post.html#comment-form' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8621678328396223325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/8621678328396223325'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/05/blog-post.html' title='政府錯了，機車才是最乾淨的交通工具'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-316213046083471407</id><published>2018-04-03T11:59:00.002+08:00</published><updated>2019-07-03T22:05:24.954+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><title type='text'>[C#] An fast way to implement Active Directory login to ASP.NET MVC</title><content type='html'>Although OWIN have a package &amp;quot;&lt;a href=&quot;https://www.nuget.org/packages/Microsoft.Owin.Security.ActiveDirectory/&quot;&gt;Microsoft.Owin.Security.ActiveDirectory&lt;/a&gt;&amp;quot; seems can support AD login, but it looks like made for ADFS, and &lt;a href=&quot;https://msdn.microsoft.com/zh-tw/library/microsoft.owin.security.activedirectory.activedirectoryfederationservicesbearerauthenticationoptions(v=vs.111).aspx&quot;&gt;leak document&lt;/a&gt; on MSDN so I dunno how to use it on basic AD login, so I decide find other way to implement AD login to MVC.&lt;br&gt;
&lt;br&gt;
After long long time search, this post &amp;quot;&lt;a href=&quot;https://stackoverflow.com/questions/33180687/owin-with-ldap-authentication&quot;&gt;OWIN with LDAP Authentication&lt;/a&gt;&amp;quot; help me a lot, my solution basic on it and add some other feature.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.died.tw/2018/04/c-fast-way-to-implement-active.html#more&quot;&gt;Read more »&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/316213046083471407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/04/c-fast-way-to-implement-active.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/316213046083471407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/316213046083471407'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/04/c-fast-way-to-implement-active.html' title='[C#] An fast way to implement Active Directory login to ASP.NET MVC'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1829213234333389814.post-1094230623016781518</id><published>2018-03-19T13:33:00.000+08:00</published><updated>2018-03-19T13:33:20.571+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell"/><title type='text'>[PowerShell] Download file and unzip | 下載檔案與解壓縮</title><content type='html'>PowerShell is an useful command tool on Windows, here I will show how to download file and unzip it.&lt;br /&gt;
PowerShell是個在Windows上很好用的指令列工具，這邊我將展示如何下載檔案和解壓縮。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #b6d7a8;&quot;&gt;Download | 下載&lt;/span&gt;&lt;/h3&gt;We using &lt;a href=&quot;https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-6&quot;&gt;Invoke-WebRequest&lt;/a&gt; to download file in Windows(like wget in linux), the command like this:&lt;br /&gt;
我們使用&lt;a href=&quot;https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-6&quot;&gt;Invoke-WebRequest&lt;/a&gt;來在Windows下載檔案(像linux的wget)，指令如下：&lt;br /&gt;
&lt;pre&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;Invoke-WebRequest&lt;/span&gt; &lt;span style=&quot;color: #e06666;&quot;&gt;-Uri&lt;/span&gt; &amp;lt;Uri&amp;gt; &lt;span style=&quot;color: #e06666;&quot;&gt;-OutFile&lt;/span&gt; &amp;lt;String&amp;gt;&lt;/pre&gt;&lt;br /&gt;
By default PowerShell uses TLS 1.0, if your file host&#39;s SSL using TLS 1.2, you will got this this error:&lt;br /&gt;
PowerShell預設使用TLS 1.0，如果你檔案網站的SSL使用TLS 1.2，你會遇到下面這個錯誤：&lt;br /&gt;
&lt;pre&gt;&lt;span style=&quot;color: red;&quot;&gt;Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
For this case, you can set PowerShell use TLS 1.2 first to avoid the error by this way.&lt;br /&gt;
在這情況，你可以用下面方式設定PowerShell優先使用TLS 1.2來避免這個問題。&lt;br /&gt;
&lt;pre&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[Net.ServicePointManager]&lt;/span&gt;::SecurityProtocol = &lt;span style=&quot;color: #6aa84f;&quot;&gt;&quot;tls12, tls11, tls&quot;&lt;/span&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;Invoke-WebRequest&lt;/span&gt; &lt;span style=&quot;color: #e06666;&quot;&gt;-uri&lt;/span&gt; https://died.github.io/us-map.zip &lt;span style=&quot;color: #e06666;&quot;&gt;-outfile&lt;/span&gt; map.zip&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #b6d7a8;&quot;&gt;Unzip | 解壓縮&lt;/span&gt;&lt;/h3&gt;The command &lt;a href=&quot;https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-6&quot;&gt;Expand-Archive&lt;/a&gt; can help us unzip file, usage like this:&lt;br /&gt;
指令&lt;a href=&quot;https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-6&quot;&gt;Expand-Archive&lt;/a&gt;可以幫我們解壓縮檔案，使用方式如下：&lt;br /&gt;
&lt;pre&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;Expand-Archive&lt;/span&gt; &amp;lt;ZipFile&amp;gt; &lt;span style=&quot;color: #e06666;&quot;&gt;-DestinationPath&lt;/span&gt; &amp;lt;String&amp;gt;&lt;/pre&gt;&lt;br /&gt;
Example | 範例 :&lt;br /&gt;
&lt;pre&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt;Expand-Archive&lt;/span&gt; .\map.zip &lt;span style=&quot;color: #e06666;&quot;&gt;-DestinationPath&lt;/span&gt; .\map\&lt;/pre&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.died.tw/feeds/1094230623016781518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.died.tw/2018/03/powershell-download-file-and-unzip.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1094230623016781518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1829213234333389814/posts/default/1094230623016781518'/><link rel='alternate' type='text/html' href='http://www.died.tw/2018/03/powershell-download-file-and-unzip.html' title='[PowerShell] Download file and unzip | 下載檔案與解壓縮'/><author><name>Died</name><uri>http://www.blogger.com/profile/17070040323517349661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>