[.net]—.net 6下載檔案

直接指向檔案路徑會報錯,要用下列方式產生檔案匯流


        [HttpGet]
        public IActionResult Index()
        {

            string fileName = HttpContext.Request.Query["filename"].ToString();
            if (fileName.Equals(""))
            {
                return View();
            } else {

                string _folder = $@"{env.WebRootPath}" + configuration.GetValue<string>("AppSetting:tmp_folder") + fileName;
                var net = new System.Net.WebClient();
                //var data = net.DownloadData(link);
                var data=System.IO.File.ReadAllBytes(_folder);
                var content = new System.IO.MemoryStream(data);
                var contentType = "application/vnd.ms-excel";
                //var fileName = "something.bin";


                System.IO.File.Delete(_folder);  


                return File(content, contentType, fileName);

            }
            

        }

黃色部份為下載完畢就刪除檔案,免得爬蟲亂抓檔案造成困擾

[.net]—.net 6使用npoi產生excel檔案

如下

public bool GenNpoiExcel(DataSet dsData, string strfileName)
        {
            NPOI.HSSF.UserModel.HSSFWorkbook workbook = new NPOI.HSSF.UserModel.HSSFWorkbook();
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            int Ii, Jj, Kk;
            NPOI.HSSF.UserModel.HSSFCell cell;
            NPOI.HSSF.UserModel.HSSFRow Row;



            for (Kk = 0; Kk < dsData.Tables.Count; Kk++)
            {
                // 新增試算表。
                NPOI.HSSF.UserModel.HSSFSheet sheet = (NPOI.HSSF.UserModel.HSSFSheet)workbook.CreateSheet(dsData.Tables[Kk].TableName);
                //插入資料值。
                //Header
                NPOI.HSSF.UserModel.HSSFRow rowItem = (NPOI.HSSF.UserModel.HSSFRow)sheet.CreateRow(0);

                for (Ii = 0; Ii < dsData.Tables[Kk].Rows.Count; Ii++)
                {

                    rowItem = (NPOI.HSSF.UserModel.HSSFRow)sheet.CreateRow(Ii);
                    for (Jj = 0; Jj < dsData.Tables[Kk].Columns.Count; Jj++)
                    {


                        rowItem.CreateCell(Jj).SetCellValue(dsData.Tables[Kk].Rows[Ii][Jj].ToString().Trim().Replace("\n", "\r\n").Replace("&nbsp;", "").Trim());
                      

                    }
                }



            }
            workbook.Write(ms);

            string _folder = $@"{env.WebRootPath}" + configuration.GetValue<string>("AppSetting:tmp_folder");


            if (!System.IO.Directory.Exists(_folder))
            {
                System.IO.Directory.CreateDirectory(_folder);
            }
            System.IO.File.WriteAllBytes(_folder + strfileName, ms.ToArray());
            
          

            workbook = null;
            ms.Close();
            ms.Dispose();
            return true;
        }

要使用 env.WebRootPath 這個方法,要在建構子宣告

  IConfiguration configuration;
        Microsoft.AspNetCore.Hosting.IWebHostEnvironment env;

        
        public RegALLComputerController(IConfiguration iConfig, Microsoft.AspNetCore.Hosting.IWebHostEnvironment ienv)
        {
            configuration = iConfig;
            env = ienv;
           
        }
[.net]—.net 6 使用非預設View路徑

放在Progrma.cs裡面

builder.Services.AddControllers();

builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
builder.Services.Configure<Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions>(o =>
{
    o.ViewLocationFormats.Clear();
    //o.ViewLocationFormats.Add("/Views/{0}" + Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.ViewExtension);
    o.ViewLocationFormats.Add("/Views/{1}/{0}" + Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.ViewExtension);
    o.ViewLocationFormats.Add("/Views/{1}/{0}/" + Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.ViewExtension);
    o.ViewLocationFormats.Add("/Views/Shared/{0}" + Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.ViewExtension);
});

就這樣,改變原本吃Pages的設定

[.net][docker] build 程式成image

基礎指令

docker build -t computerreg:1.3 -f Dockerfile .

原本以為微軟應該很人性化的,只要加入Dockerfile,應該就可以乖乖build

結果我依然是太天真了,這樣只會踩坑XD

原因出在紅匡處

Web專案有參考到額外兩個專案的輸出,所以直接Build是不會過的,要手動複製Dockerfile,到上一層,然後指令先下 cd..,移到上一層,再下



docker build -t computerreg:1.3 -f Dockerfile .

成功

[ubuntu][.net] ubuntu安裝.net 6 framework
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-6.0

最後檢查的部份

dotnet --list-sdks

有出現版本代表安裝成功

[.net 5]讓Web同時擁有API的功能
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace web
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddRazorPages();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapControllers();
            });
        }
    }
}

根目錄再自行加上Controllers資料夾

就可以運作了

[.net]允許html字元(開放XSS)

asp.net有兩個地方要調整

網頁前面加上validateRequest=”False”

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ddd.aspx.cs" Inherits="sss.ddd" validateRequest="False" %>

web config 加上

<configuration>

  <location path="ddd.aspx">
    <system.web>
      <httpRuntime requestValidationMode="2.0" />
    </system.web>
  </location>
</configuration>

mvc則是這樣

  [HttpPost]
  [ValidateInput(false)]
  public PppResult PostPpp

[nodejs][.net]加解密

c# code

public class DecryptHelper
    {
        /// <summary>
        /// 做AES的解密 PKCS5Padding補碼
        /// </summary>
        /// <param name="text">解密的字串</param>
        /// <param name="key">key</param>
        /// <param name="iv">iv</param>
        /// <returns>解密後的字串</returns>
        public  string DecryptAES(string text, string key, string iv)
        {
            //var encryptBytes = System.Convert.FromBase64String(text);
            var encryptBytes = hex2byte(text);
            var aes = new System.Security.Cryptography.RijndaelManaged();
            aes.Mode = System.Security.Cryptography.CipherMode.CBC;
            aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
            aes.Key = System.Text.Encoding.ASCII.GetBytes(key);
            aes.IV = System.Text.Encoding.UTF8.GetBytes(iv);
            var transform = aes.CreateDecryptor();
            return System.Text.Encoding.UTF8.GetString(transform.TransformFinalBlock(encryptBytes, 0, encryptBytes.Length));

        }

        private  byte[] hex2byte(string strhex)
        {
            if (strhex == null)
            {
                return null;
            }
            int l = strhex.Length;
            if (l % 2 == 1)
            {
                return null;
            }
            byte[] b = new byte[l / 2];
            for (int i = 0; i != l / 2; i++)
            {
                b[i] = Convert.ToByte(strhex.Substring(i * 2, 2),
                        16);
            }
            return b;
        }
    }
  public class EncryptHelper
    {
        public string EncryptionBySHA256AndUrlEncode(string str)
        {
            return Uri.EscapeDataString(EncryptionBySHA256(str));//輸出結果
        }
        public string EncryptionBySHA256(string password)
        {
            if (password == null || password == "" || password == string.Empty)
                throw new Exception("EncryptionHelper-->EncryptionBySHA256  password is empty");
            try
            {
                SHA256 sha256 = new SHA256CryptoServiceProvider();//建立一個SHA256
                byte[] source = Encoding.Default.GetBytes(password);//將字串轉為Byte[]
                byte[] crypto = sha256.ComputeHash(source);//進行SHA256加密
                string result = Convert.ToBase64String(crypto);//把加密後的字串從Byte[]轉為字串
                return result;//輸出結果
            }
            catch (Exception e)
            {
                throw new Exception("EncryptionBySHA256 error " + e.ToString());
            }
        }


        /// <summary>
        /// 做AES的加密 PKCS5Padding補碼
        /// </summary>
        /// <param name="text">加密的字串</param>
        /// <param name="key">key</param>
        /// <param name="iv">iv</param>
        /// <returns>加密後的字串</returns>
        public string EncryptAES(string text, string key, string iv)
        {
            var sourceBytes = System.Text.Encoding.UTF8.GetBytes(text);
            var aes = new System.Security.Cryptography.RijndaelManaged();
            aes.Mode = System.Security.Cryptography.CipherMode.CBC;
            aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
            aes.Key = System.Text.Encoding.UTF8.GetBytes(key);
            aes.IV = System.Text.Encoding.UTF8.GetBytes(iv);
            var transform = aes.CreateEncryptor();
            return byte2hex(transform.TransformFinalBlock(sourceBytes, 0, sourceBytes.Length)).ToUpper();
        }

        private string byte2hex(byte[] b)
        {
            return BitConverter.ToString(b).Replace("-", "").ToUpper();
        }
    }

呼叫方式

    Dim IVAES As String = "20211208125030AV"
    Dim KEYAES As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"

'加密
Dim AES As New AES.EncryptHelper
       
        txtEpcy.Text = AES.EncryptAES(txtOrg.Text, KEYAES, IVAES)
'解密
Dim AES As New AES.DecryptHelper
        txtOrg.Text = AES.DecryptAES(txtEpcy.Text, KEYAES, IVAES)

nodejs

const Rijndael = require('rijndael-js');
const padder = require('pkcs7-padding');


const plainText = Buffer.from('OOXXZZ', 'utf8');

const padded = padder.pad(plainText, 16); //Use 32 = 256 bits block sizes,16=128 bits block sizes

const iv = stringToByteArray('20211208125030AV'); //16
const key = stringToByteArray('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef'); //32 

const cipher = new Rijndael(key, 'cbc'); //CBC mode
const encrypted = cipher.encrypt(padded, 128, iv);
var text=toHexString(encrypted);
console.log(text);




const decryptedPadded = cipher.decrypt(toByteArray(text), 128, iv);
const decrypted = padder.unpad(decryptedPadded, 16);
const clearText = Buffer.from(decrypted, 'utf8').toString();

console.log(clearText);

function stringToByteArray(s) {

    // Otherwise, fall back to 7-bit ASCII only
    var result = new Uint8Array(s.length);
    for (var i = 0; i < s.length; i++) {
        result[i] = s.charCodeAt(i);/* w ww. ja  v  a 2s . co  m*/
    }
    return result;
}
function toByteArray(text) {
    let Arr=[];
    let Size = text.length;
    let Ii = 0;
    let tmp = "";
    for (Ii = 0; Ii < Size ; Ii=Ii+2) {
        tmp = text.substring(Ii, Ii + 2);
        //console.log("找到:" + tmp);
        Arr.push(Number("0x" + tmp));

    }
    return Arr;
}
function toHexString(byteArray) {
    return Array.from(byteArray, function (byte) {
        return ('0' + (byte & 0xFF).toString(16).toUpperCase()).slice(-2);
    }).join('')
}

結果是

C272F8B1012302282879DFE20ED6B3E5
sefsgdthfjutyikyugku