UWInfo Blog
發表新文章
[Join] | [忘記密碼] | [Login]
搜尋

搜尋意見
文章分類-#Author#
[所有文章分類]
所有文章分類
  • ASP.NET (48)
  • ASP.NET2.0 (15)
  • ASP.NET4.0 (34)
  • JavaScript (49)
  • jQuery (26)
  • FireFox (4)
  • UW系統設定 (3)
  • SQL (39)
  • SQL 2008 (25)
  • mirror (4)
  • SVN (4)
  • IE (9)
  • IIS (20)
  • IIS6 (1)
  • 閒聊 (7)
  • W3C (6)
  • 作業系統 (9)
  • C# (24)
  • CSS (12)
  • FileServer (1)
  • HTML 5 (11)
  • CKEditor (3)
  • UW.dll (13)
  • Visual Studio (16)
  • Browser (8)
  • SEO (1)
  • Google Apps (3)
  • 網站輔助系統 (4)
  • DNS (5)
  • SMTP (4)
  • 網管 (11)
  • 社群API (3)
  • SSL (4)
  • App_Inventor (1)
  • URLRewrite (2)
  • 開發工具 (6)
  • JSON (1)
  • Excel2007 (1)
  • 試題 (3)
  • LINQ (1)
  • bootstrap (0)
  • Vue (3)
  • IIS7 (3)
  • foodpanda (2)
  • 編碼 (2)
  • 資安 (3)
  • Sourcetree (1)
  • MAUI (1)
  • CMD (1)
  • my sql (1)
最新回應
  • Newtonsoft.Json.JsonConvert.DeserializeObject 失敗的情況
    test...more
  • dotnet ef dbcontext scaffold
    ...more
  • [ASP.NET] 利用 aspnet_regiis 加密 web.config
    ...more
  • IIS ARR (reverse proxy) 服務安裝
    ...more
  • [錯誤訊息] 請加入 ScriptResourceMapping 命名的 jquery (區分大小寫)
    ...more
  • 用 Javascript 跨網頁讀取 cookie (Cookie cross page, path of cookie)
    ...more
  • 線上客服 - MSN
    本人信箱被盜用以致資料外洩,是否可以請貴平台予以協助刪除該信箱之使用謝謝囉...more
  • 插入文字到游標或選取處
    aaaaa...more
  • IIS 配合 AD (Active Directory) 認証, 使用 .Net 6.0
    太感謝你了~~~你救了我被windows 認證卡了好幾天QQ...more
  • PostgreSQL 的 monitor trigger
    FOR EACH ROW 可能要改為 FOR EACH STATEMENT ...more
標籤
  • blog
  • 15.1MQtn
  • [u2]
  • asp.net
  • column
  • ip
  • tim
  • SQL
  • 一致性
  • AD
  • unicode
  • 412
  • CK
  • .
  • z-index
  • gmail
  • 70
  • 整數
  • ef
  • DB備份
  • CSR
  • 726
  • 8468
  • -5846
  • -5672
  • -5103 UNIO
  • -4768
  • -4563
  • end
  • -3373
  • -2755
  • -2154 UNIO
  • 20
  • [t]
  • DTToExcelA
  • sql table
  • ref與out
  • jquery
  • 三元
  • 帳號
  • vs
  • 28
  • ssl lab
  • a
  • 9604
  • s3
  • 檔案
  • domain
  • pw
  • 162
頁數 1 / 3 下一頁
搜尋 移 結果:
解決 jquery XSS問題,升級到 3.5 版以上之相關處理
最近因為資安公司要求,要把 jQuery 升級到最新版
網路查了一下,似乎 3.5 版以後, XSS 才算是改善很多

目前最新版本是 3.7.0,對於原本就使用 3 以上版本專案影響就不大,所有 function 沿用上沒有問題
但是有些舊專案使用 2.X 甚至 1.X 升級到 3.7.0 版之後就會有些功能掛掉

經測試,首當其衝的就是 $(window).load 不能使用,更精準一點應該是 .load() 不能使用
檢查 jquery 過期網頁 https://api.jquery.com/category/deprecated/
發現 .load() 是 1.8 版以後 deprecated,但我 2.2.4 用很久用爽爽
我想應該是 jquery 為了相容問題,一直到跨版本才真的拿掉
也就是 1.X 宣告 deprecated 的功能,到 3.X 才真的移除
(請看附圖)
所以我就鴕鳥的找 1.X  deprecated 然後可能會用的 function 處理
(若有 tag "Removed" 就是已移除,這樣找比較快)
.andSelf()
.live()
.die()
.error()
.load()
.unload()
.size()
.toggle()

大致上專案搜尋字串應該就能處理
但有些可能是其他第三方 jquery物件 例如 jquery-ui ,會用到以上功能
這時可能要去該物件看有無對應升級版
 
More...
darren, 2023/7/20 上午 11:08:33
Sourcetree 重新安裝
Sourcetree重新安裝(完整清除舊資料)

1. 移除電腦上的Sourcetree軟體
2. 備份以下檔案後,然後刪除:
路徑:C:\Users\<UserName>\AppData\Local  刪除 SourceTree 資料夾
路徑:C:\Users\<UserName>\AppData\Local\Atlassian 刪除 SourceTree 資料夾
路徑:C:\Users\<UserName>\AppData\Roaming\Atlassian 刪除 SourceTree 資料夾
3. 重新下載Sourcetree軟體進行安裝

參考來源:
https://community.atlassian.com/t5/Sourcetree-questions/How-do-I-fully-remove-SourceTree-so-that-I-can-do-a-quot-fresh/qaq-p/1448403
More...
choco, 2023/2/2 上午 08:13:27
.Net 6 的 Captcha 實做
產生 FileStreamResult 物件的 function 如下: (目前置於 SU 之中,以便轉移)

        static List<Brush> CaptchaBrushes = null;
        public static FileStreamResult CreateCaptcha(string captcha)
        {
            if (CaptchaBrushes == null)
            {
                CaptchaBrushes = new List<Brush>();
                CaptchaBrushes.Add(Brushes.White);
                CaptchaBrushes.Add(Brushes.Gold);
                CaptchaBrushes.Add(Brushes.LightSkyBlue);
                CaptchaBrushes.Add(Brushes.LimeGreen);
                CaptchaBrushes.Add(Brushes.AliceBlue);
                CaptchaBrushes.Add(Brushes.AntiqueWhite);
                CaptchaBrushes.Add(Brushes.BurlyWood);
                CaptchaBrushes.Add(Brushes.Silver);
            }

            int width = 90;
            int height = 45;

            //https://stackoverflow.com/questions/61365732/cannot-access-a-closed-stream-when-returning-filestreamresult-from-c-sharp-netc
            //Using statements close and unload the variable from memory set in the using statement which is why you are getting an error trying to access a closed memory stream.You don't need to use a using statement if you are just going to return the result at the end.

            //這個 memory stream 不用關閉或 dispose
            var ms = new MemoryStream();

            // 釋放所有在 GDI+ 所佔用的記憶體空間 ( 非常重要!! )
            using (Bitmap _bmp = new Bitmap(width, height))
            using (Graphics _graphics = Graphics.FromImage(_bmp))
            using (Font _font = new Font("Courier New", 24, FontStyle.Bold)) // _font 設定要出現在圖片上的文字字型、大小與樣式
            {
                // (封裝 GDI+ 繪圖介面) 所有繪圖作業都需透過 Graphics 物件進行操作
                _graphics.Clear(Color.Black);

                // 如果想啟用「反鋸齒」功能,可以將以下這行取消註解
                //_graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

                // 將亂碼字串「繪製」到之前產生的 Graphics 「繪圖板」上
                var x = 10;
                for(var i = 0; i < captcha.Length; i++)
                {
                    _graphics.DrawString(captcha.Substring(i, 1), _font, CaptchaBrushes[Su.MathUtil.GetRandomInt(CaptchaBrushes.Count)], x, Su.MathUtil.GetRandomInt(15));
                    x += 10 + Su.MathUtil.GetRandomInt(10);
                }

                // 畫線
                
                _graphics.DrawLine(new Pen(CaptchaBrushes[Su.MathUtil.GetRandomInt(CaptchaBrushes.Count)], 1),
                    Su.MathUtil.GetRandomInt(0, Convert.ToInt32((width * 0.9 / 2))), 0, Su.MathUtil.GetRandomInt(Convert.ToInt32(width / 2), Convert.ToInt32(width * 1.9 / 2)), height);
                
                _graphics.DrawLine(new Pen(CaptchaBrushes[Su.MathUtil.GetRandomInt(CaptchaBrushes.Count)], 1),
                    Su.MathUtil.GetRandomInt(Convert.ToInt32(width / 2), Convert.ToInt32(width * 1.9 / 2)), 0, Su.MathUtil.GetRandomInt(0, Convert.ToInt32((width * 0.9 / 2))), height);
                
                _graphics.DrawLine(new Pen(CaptchaBrushes[Su.MathUtil.GetRandomInt(CaptchaBrushes.Count)], 1),
                    0,
                    Su.MathUtil.GetRandomInt(height / 2),
                    width,
                    height / 2 + Su.MathUtil.GetRandomInt(height / 2)
                    );

                _graphics.DrawLine(new Pen(CaptchaBrushes[Su.MathUtil.GetRandomInt(CaptchaBrushes.Count)], 1),
                 0,
                 height / 2 + Su.MathUtil.GetRandomInt(height / 2),
                 width,
                    Su.MathUtil.GetRandomInt(height / 2)
                 );

                _bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            }

            ms.Seek(0, SeekOrigin.Begin);

            // Controller 的型別為 FileResult
            return new FileStreamResult(ms, "image/jpeg")
            { FileDownloadName = $"{DateTime.Now.Ymdhmsf()}.jpg" };
        }



輸出用的 Controller 和 Action 如下:

namespace Web.Controllers
{
    public class CaptchaController : Controller
    {
        [Route("captcha")]
        public async Task<FileStreamResult> Index()
        {
            //產生 Captcha 並存入 Session 之中。目前是四位數字
            string captcha = (await Ah.ReGetAsync<object>("api/kol/create-captcha-code")).ToString();

            //產生圖檔並回傳 FileStreamResult
            return Su.Wu.CreateCaptcha(captcha);
        }
    }
}
More...
Bike, 2022/9/25 下午 10:03:44
VS 建立虛擬目錄導致HttpHandler重複錯誤
 
於VS Web中建立虛擬目錄,導致Swagger Handler出現重複錯誤
主要原因是因為跟網站與子網站指向同一個資料夾,而父子網站的web.config有繼承關係導致。

解決方式:
1. 前往 根目錄 / .vs / 專案 / config / applicationhost.config

2. 將site中設定的子網站移除或變更虛擬目錄位置

 
3. 回到網頁重新整理就完成囉!

參考: 【茶包射手日記】怪異的web.config HttpHandler重複錯誤
More...
梨子, 2022/7/1 上午 11:57:02
C# 元組與分解 (Tuple And Deconstruct)
*分解元組(Deconstructing tuples)的支援必須要至少C# 7.0以上*

以前一個funtion如果需要回傳複數個參數你會怎麼做呢?

1.可能會定義一個物件,在回傳的時候宣告並將值塞進去return。(為了一個function而去定義,好醜...)
2.又或者是將回傳參數型別直接改成dynamic,回傳時直接使用匿名物件。(performance炸裂!!!)

如果你使用了上面兩種方式...請一定!一定!!一定!!!要把這篇文章看完。

先來說說在C#7.0以前的處理方法,在呼叫function之前先將欲接收的參數宣告好並傳入。



但是這樣做有幾個缺點,
1. 當傳入的參數與傳出的參數一多起來,function定義時的參數會又臭又長。
2. 使用這個function前每次都需要宣告變數,不累嗎?
3. 不管你要不要使用這個參數,你都一定要傳入,因為ref與out不能有預設值。

接下來...讓我與各位介紹 " 元 組 元 素 "!!! (Tuple)

早上好台灣,現在我有Tuple。我很喜歡Tuple,但是速度與激情9比...咳咳...沒事。

先來個簡單的範例

定義一個funciton JohnCena

然後我們就可以很漂亮的一次性取得JohnCena的姓名、出生日期、國籍、年齡等等資料!

 
假如你的參數需要在外面先行宣告也沒問題!



而從C#10開始,甚至可以混合使用也沒關係!



這樣我們就輕鬆解決了以前的兩個缺點了,而要解決最後一個缺點更是簡單,
只需要將你想要丟棄(discard)或是用不到的那個參數使用UnderLine( _ )就可以囉!



元組元素的基礎講完了再來說說解構元素的部分
建構式想必大家都已經很熟悉了



但是'分解式'你有聽過嗎?
顧名思義就是可以定義物件被指派出去的參數!
驚不驚喜! 意不意外?

使用的方法就是在class底下新增一個Deconstruct function



如此一來我們就可以來試試看將John Cena解ㄊ一.... 分解!



建構式可以多載,分解式當然也可以!



以上就是這次的內容,有沒有覺得Coding時的可玩性又更好了呢?
不過要提醒一點,目前解構式並無法使用查看定義來移置相對應的位置,
對於可讀性會有不小的影響,但如果你想要把某個東西藏起來不讓你同事找到... (請不要這樣做!)
這次的範例也歡迎到我的GitHub參考囉!

06/09/2022   由Bike 補充
 
可以將function的回傳參數先行命名!!
直接當成物件使用,對開發效率與可讀性有著明顯的提升,相信會是未來的趨勢。

另外要道歉並修正之前將Deconstruct翻譯成解構式的錯誤
Destruct (解構式)指的是class生命周期結束前執行的function
使用方式是class名稱為dunction名稱並在前面加上波浪符號 '~'
Deconstruct的翻譯應該為分解式
More...
梨子, 2022/5/26 下午 07:58:00
使用Lucene.Net達成全文檢索!基礎解說(二)
上一集當中我們完成了Lucene基本操作中的Create與Read,這一集會將CRUD中的Update與Delete的操作方法告訴你,並且本集會著重於講解關於"Norms"與權重(Boost)在Lucene中的運作概念。

首先我們建立一個.Net 6的主控台應用程式
   

建立好後於右側專案右鍵選擇"管理Nuget套件",並選擇"瀏覽">於搜索列中搜尋"Lucene">安裝3.0.3最新穩定版 與 "System.Configuration.ConfigurationManager"

 
 安裝好後就可以於專案內使用Lucene套件囉!
再來依照上一篇的教學建立一套簡單的Lucene查詢

using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;

var _dir = new DirectoryInfo("LuceneDocument");
if (!File.Exists(_dir.FullName))
{
    System.IO.Directory.CreateDirectory(_dir.FullName);
}
var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_CURRENT);
CreateIndex(GetProductsInformation(), _dir, analyzer);

while (true)
{
    Console.Write("請輸入欲查詢字串 :");
    var searchValue = Console.ReadLine();
    Search(searchValue, _dir, analyzer);
}

void CreateIndex(List<Product> information, DirectoryInfo dir, StandardAnalyzer analyzer)
{
    using (var directory = FSDirectory.Open(dir))
    {
        using (var indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED))
        {
            foreach (var index in information)
            {
                var document = new Document();
                document.Add(new Field("Id", index.Id.ToString(), Field.Store.YES, Field.Index.NO));
                document.Add(new Field("Name", index.Name, Field.Store.YES, Field.Index.ANALYZED));
                document.Add(new Field("Description", index.Description, Field.Store.YES, Field.Index.ANALYZED));
                indexWriter.AddDocument(document);
            }
            indexWriter.Optimize();
            indexWriter.Commit();
        }
    }
}
void Search(string searchValue, DirectoryInfo dir, StandardAnalyzer analyzer)
{
    using (var directory = FSDirectory.Open(_dir))
    {
        var parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "Description", analyzer).Parse(searchValue);
        using (var indexSearcher = new IndexSearcher(directory))
        {
            var queryLimit = 20;
            var hits = indexSearcher.Search(parser, queryLimit);
            if (!hits.ScoreDocs.Any())
            {
                Console.WriteLine("查無相關結果。");
                return;
            }
            Document doc;
            foreach (var hit in hits.ScoreDocs)
            {
                doc = indexSearcher.Doc(hit.Doc);
                Console.WriteLine("Score :" + hit.Score + ", Id :" + doc.Get("Id") + ", Name :" + doc.Get("Name") + ", Description :" + doc.Get("Description"));
            }
        }
    }
}

List<Product> GetProductsInformation()
{
    return new List<Product> {
            new Product{ Id = 1, Name = "蘋果", Description = "一天一蘋果,醫生遠離我。"},
            new Product{ Id = 2, Name = "橘子", Description = "醫生給娜美最珍貴的寶藏。"},
            new Product{ Id = 3, Name = "梨子", Description = "我是梨子,比蘋果好吃多囉!"},
            new Product{ Id = 4, Name = "葡萄", Description = "吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮"},
            new Product{ Id = 5, Name = "榴槤", Description = "水果界的珍寶!好吃一直吃。"}
        };
}
class Product
{
    public long Id { get; set; }
    public string Name { get; set; } = null!;
    public string Description { get; set; } = null!;
}


好囉! 接下來我們要如何更新索引呢?
更新其實就是將存在的索引刪除並重新建立Document,不存在的則直接新增。
首先準備一組資料準備更新

List<Product> GetUpdateProductsInformation()
{
    return new List<Product>
    {
        new Product{ Id = 6, Name = "香蕉", Description = "運動完後吃根香蕉補充養分。"},
        new Product{ Id = 2, Name = "橘子", Description = "橘子跟柳丁你分得出來嗎?"}
    };
}


*欲更新的Document必須與創建所引時使用的Document欄位相同*

void Update(string key, List<Product> information, DirectoryInfo dir, StandardAnalyzer analyzer)
{
    using( var directory = FSDirectory.Open(dir))
    {
        using(var indexWriter = new IndexWriter(directory, analyzer, false, IndexWriter.MaxFieldLength.LIMITED))
        {
            foreach (var index in information)
            {
                var document = new Document();
                document.Add(new Field("Id", index.Id.ToString(), Field.Store.YES, Field.Index.NO));
                document.Add(new Field("Name", index.Name, Field.Store.YES, Field.Index.ANALYZED));
                document.Add(new Field("Description", index.Description, Field.Store.YES, Field.Index.ANALYZED));
                indexWriter.UpdateDocument(new Term("Name", key) ,document);
            }
        }
    }
}


來測試看看
   
可以看見 Name = 橘子 的索引已經改為我們新準備的資料囉。
再來是刪除!
與更新非常相似,只需要使用deleteDocument()就可以了。

void Delete(string key, DirectoryInfo dir, StandardAnalyzer analyzer)
{
    using (var directory = FSDirectory.Open(dir))
    {
        using (var indexWriter = new IndexWriter(directory, analyzer, false, IndexWriter.MaxFieldLength.LIMITED))
        {
            indexWriter.DeleteDocuments(new Term("Name", key));
            indexWriter.Optimize();
            indexWriter.Commit();
        }
    }
}


再來看看輸出結果
 可以發現 Score :0.7554128, Id :2, Name :橘子, Description :醫生給娜美最珍貴的寶藏。這筆索引已經被移除囉!
  
可以發現筆者於更新或刪除時都是輸入單一字來做異動,除了表達可以對索引做複合更動外,
是因為更新與刪除索引同樣會使用到分詞器(analyzer),
*所輸入的索引值非ID等數值時必須要配合分詞器的分詞能力*才能取得所想異動的索引喔!


Boost是什麼呢?
Boost 分為 :
1. Index Time Boost : 在建立索引時就計算好的值。例如上一篇中提到的(NORMS)
2. Query Time Boost : 查詢時賦與搜尋條件不同的值以影響結果。
我們先來測試Index Time Boost的部分
void CreateIndexWithBoost(List<Product> information, DirectoryInfo dir, StandardAnalyzer analyzer)
{
    using (var directory = FSDirectory.Open(dir))
    {
        using (var indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED))
        {
            foreach (var index in information)
            {
                var document = new Document();
                document.Add(new Field("Id", index.Id.ToString(), Field.Store.YES, Field.Index.NO));
                document.Add(new Field("Name", index.Name, Field.Store.YES, Field.Index.ANALYZED));
                document.Add(new Field("Description", index.Description, Field.Store.YES, Field.Index.ANALYZED));
                document.GetField("Name").Boost = 1.5F;
                document.GetField("Description").Boost = 0.5F;

                indexWriter.AddDocument(document);
            }
            indexWriter.Optimize();
            indexWriter.Commit();
        }
    }
}


並記得重新CreateIndex才能刷新欄位的權重值喔。


很明顯的搜尋出來的Score分數變動了! 但是有沒有發現明明Name欄位的Boost改成了1.5,蘋果的數值卻仍然只有一半呢?
這是因為我們的Search中所參照的欄位為Description,所以在計算Score的時候其實是完全沒有參與的喔!
另外要記得,使用Index Time Boost的時候,欲給予銓重分配的欄位Field.Index不能使用NO_NORMS,不然這個欄位並不會紀錄權重的資料。

再來我們試試看Query Time Boost
void SearchWithBoost(string searchValue, DirectoryInfo dir, StandardAnalyzer analyzer)
{
    using (var directory = FSDirectory.Open(_dir))
    {
        using (var indexSearcher = new IndexSearcher(directory))
        {
            var query = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "Name", analyzer).Parse(searchValue);
            var query2 = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "Description", analyzer).Parse(searchValue);

            query.Boost = 2.0F;
            query2.Boost = 0.5F;

            BooleanQuery booleanQuery = new BooleanQuery();
            booleanQuery.Add(query, Occur.SHOULD);
            booleanQuery.Add(query2, Occur.SHOULD);

            var hits = indexSearcher.Search(booleanQuery, 20);
            if (!hits.ScoreDocs.Any())
            {
                Console.WriteLine("查無相關結果。");
                return;
            }
            Document doc;
            foreach (var hit in hits.ScoreDocs)
            {
                doc = indexSearcher.Doc(hit.Doc);
                Console.WriteLine("Score :" + hit.Score + ", Id :" + doc.Get("Id") + ", Name :" + doc.Get("Name") + ", Description :" + doc.Get("Description"));
            }
        }
    }
}


這次我們搜尋兩個欄位"Name"與"Description",並使用 BooleanQuery來將其組合。
BooleanQuery中的 Occur有三種參數 : "MUST","MUST_NOT","SHOULD",功能與字面上的意思一樣為"必須要有","必須沒有"與"有無都包含"。

 
查詢出來的分數就不一樣囉!

以上就是這一次的分享,Lucene是一款容易入門但是要實際上戰場卻又十分複雜的功能,想要達成真正高效能的全文檢索,在前期的文件規畫配置與資料的權重配比都是一個巨大的挑戰。未來會繼續分享關於Lucene的其他有趣功能,還請繼續期待呦!
另外也可以到GitHub下載我的範例來參考呦!
GitHub: https://github.com/g13579112000/Lucene

參考文件:
1. 黑暗大大的全文檢索筆記 : https://blog.darkthread.net/blog/lucene-net-notes-1/
2. Makble : http://makble.com/lucene-field-boost-example
3. CSDN Jack2013tong 文章 : https://blog.csdn.net/huwei2003/article/details/53408388
More...
梨子, 2022/4/20 下午 09:34:03
Visual Studio ashx檔 無出現程式碼的自動完成 (Code intelligence)
2022.06.22
1) 後來發現更新這兩個檔案就可以了
參考來源:
https://docs.microsoft.com/zh-tw/dotnet/framework/install/guide-for-developers

2) 要記得把文字編輯器>副檔名的設定移除
3) 注意web.config 中 targetFramework 的版本 不能太舊
targetFramework ="4.6.1"

----------------------------------------------

最近安裝新版的Visual Studio 2022
發現ashx檔案沒有自動排版與程式碼相關名稱可以自動代入
找了一陣子才找到, 使用後發現不會檢查程式是否有錯誤..
但還是紀錄一下

開啟Visual Studio 於選單
工具>選項

文字編輯器>副檔名

 
More...
choco, 2022/2/11 上午 09:10:08
SU 的新規格 RFP
1. .Net Core 5.0 使用.
2. 可切換後, 適用於 MsSQL, MySql, Oracle
3. 預設所有 SQL 執行時要經過 SQL Injection 檢查.
(移除 "CheckDangerSQL", 併入 IsSqlInjection) 

預設會把 CR 和 LF 換成 空白,以免 sql injection 檢查發生錯誤, 有參數可以控制這個行為。sql 和 資料應該要分開,sql 中的 CR 和 LF 被換成空白應該不會有問題。

4. 不要再使用 SqlStr, 改用 SqlValue (避免誤用, SqlStr 有一個問題, 若是忘了加上 '' 會有可能造成 sql injection)

5. ORM 的 Class Name, 若遇到全大寫的字節, 要先轉小寫, 再把第一個字母變大寫.

6. CopyPropertiesTo, CopyTo.. 
   SetValue 時, 若發生錯誤, 要顯示錯誤欄位名稱. (Tmi 的版本, ObjUtil.cs)

7. CopyFromDataRow: 
   string 自動轉 DateTime
   string 自動轉  int, long, decimal..

8. Criteria 的 In 和 operator (|) 要接 list 做為參數, 不要再直接用字串做參數.

9. OrderBy 增加 by column 且可以多個串接

10. Update 時可以用 sql 語法 (參考聖宜的  GetSetFieldWithExpression)

11. 檢查 SQL Injection 的方法改為先把 \r 和 \n 用空白取代,再檢查, 再取代參數。

12. DtFromSql 和 ExecuteSql 傳入 connection 和 transaction 的版本先刪除,未來有需要再增加。 
More...
Bike, 2021/10/18 下午 04:29:15
Swagger 的問題解決 (NSwag)
在 .Net Core 的專案使用 NSwag 時遇到: Unable to render this definition, The provided definition does not specify a valid version field. 錯誤. 有點一頭霧水, 最後解決了, 大概記錄一下解決的過程:




1. 把所有的 Controller 全部移. 再開啟 /swager, 此時應該會有空的 swager 頁面, 若異常, 則應該是 NSwag 沒裝好.

2. 把 Controller 一個一個加入專案, 每加入一個, 就開啟一次 /swager 的頁面, 若是發現異常, 就是那個 controller 有問題.

3. 找到有問題的 Controller 之後, 可以把內容先全部註解掉, 然後再一個一個的把 function 加回 controller, 應該就可以找到造成問題的 Action. 該問題有可能是以下情況造成:
    A. Action 沒有指定存取的 method.
    B. 不是 Action 的 function 被設定為 public (在 Controller 裡面, 非提供 client 端存取的 function, 都不應被設為 public)
    C. 這個很神奇, 註解也有可能造成問題, 試著把該 Action 的註解刪除, 再重新加入, 說不定就會好了.



 
另外, 使用 swagger 時, 要記得在專案的屬性的建置選項中, 要勾選 XML 註解輸出, 才會自動把  Action 的註解變成說明文字.:

 
 
More...
Bike, 2021/8/2 上午 05:00:21
政府GPO組態設定 & 所遇到的問題及解決方式
這次因為小三美日要架設新機房設備,所以採用政府GPO的群組原則來提升安全性,關於設定的方式可由以下的附檔內說明使用,

在安裝GPO後,會遇到的問題及解決方式如下

1. 在安裝後發現原先預設使用的administrator帳號被停用,導致無法登入。
    解決:在安裝GPO前,先換一個新的管理權限帳號即可

2. 想要安裝IIS或是hyper-v(新增角色)時,發現安裝權限已被停用。
    解決:先搜尋到gpedit.msc,檢查電腦設定 \ 系統管理範本 \ Windows元件 \ Windowsl遠端殼層 \ 允許遠端殼層存取,是否為  已啟用

3.使用hyper-v安裝windows,再安裝GPO後,發現無法從hyper-v的console登入。
   解決:搜尋gpedit.msc,檢查電腦設定 \ windows設定 \ 安全性設定 \ 使用者權限指派 \ 拒絕透過遠端桌面服務登入,移除本機帳戶

4.使用hyper-v配合GPO會無法將本機的資源(檔案)丟到虛擬主機。
  解決:檢查電腦設定 \ 系統管理範本 \ windows 元件 \ 遠端桌面服務 \ 遠端桌面工作階段主機 \ 裝置及資源重新導向,將不允許磁碟機重新導向,設定為已停用
另外,搜尋gpedit.msc,檢查電腦設定 \ windows設定 \ 安全性設定 \ 使用者權限指派 \ 拒絕從網路存取這台電腦,移除管理權限帳戶

以上設定完後,最好在自己系統的cmd中,輸入gpupdate /force,直接更新原則

 
More...
nelson, 2020/9/16 上午 07:29:19
|< 123 >|
頁數 1 / 3 下一頁
~ Uwinfo ~