希格工作室

2019年9月30日 星期一

.NET Core 2.1 DI AddDbContext BUG

.NET Core 2.1 bug

錯誤訊息:
No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

原因:
透過AddDbContext進來的EFCore會發生optionsBuilder.IsConfigured永遠為true,造成無法運作,直到更新至2.1.11才被修正

過程:
Code-first加入方式Scaffold-DbContext

Startup.cs
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddDbContext<Models.Test.TContext>();
        }


ValuesController.cs
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly Models.Test.TContext context;

        public ValuesController(Models.Test.TContext context)
        {
            this.context = context;
        }

        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            var tb = context.Table2.FirstOrDefault();
            return new string[] { "value1", "value2" };
        }
    }
}


Context.cs








修正方式:
三種修正方式(擇一即可)
1.更新至.Net Core 2.1.11up或.Net Core 2.2
2.如果將Context透過繼承也會避開
3.改使用AddTransient<T>註冊



2.將Context透過繼承也會避開















































3.改使用AddTransient<T>註冊












結語:
能更新上去就更新上去,但因為我平台在AWS上,而aws toolkit for visual studio的預設專案範本不支援.NET Core2.2up,若要使用過於複雜不適合目前環境,故只能持續使用2.1版,所以更新2.1.11版是最佳解,其次是透過繼承也能順便解決其它自定義的東西。





2019年9月23日 星期一

aws toolkit for visual studio & Lambda & serverless.template

記錄在VisualStudio上開發AWSLambda時,發行的重點

serverless.template

{
 "AWSTemplateFormatVersion" : "2010-09-09",
 "Transform" : "AWS::Serverless-2016-10-31",
 "Description" : "An AWS Serverless Application that uses the ASP.NET Core framework running in Amazon Lambda.",

 "Parameters" : {
  "ShouldCreateBucket" : {
   "Type" : "String",        
   "AllowedValues" : ["true", "false"],
   "Description" : "If true then the S3 bucket that will be proxied will be created with the CloudFormation stack."
  },  
  "BucketName" : {
   "Type" : "String",
   "Description" : "Name of S3 bucket that will be proxied. If left blank a name will be generated.",
   "MinLength" : "0"
  },  
  //此處可自訂發行欄位,例如資料庫的連線字串
  "connectionStrings" : {
   "Type" : "String",
   "Description" : "資料庫連線字串",
   "NoEcho":"false",
   "MinLength" : "0"
  }
 },

 "Conditions" : {
  "CreateS3Bucket" : {"Fn::Equals" : [{"Ref" : "ShouldCreateBucket"}, "true"]},
  "BucketNameGenerated" : {"Fn::Equals" : [{"Ref" : "BucketName"}, ""]}
 },

 "Resources" : {

   "AspNetCoreFunction" : {
    "Type" : "AWS::Serverless::Function",
    "Properties": {
    //此處的值是由程式自動生成,沒需要動
    "Handler": "Service_xxx::Service_xxx.LambdaEntryPoint::FunctionHandlerAsync",
    "Runtime": "dotnetcore2.1",
    "CodeUri": "",
    "MemorySize": 256,
    "Timeout": 30,
    //此處可以自定aws的規則,如果要加入VPC的話,可以選擇在後台上建立一個Role並加入AWSLambdaVPCAccessExecutionRole的權限後,填入此處即可
    "Role": null,
    //承上,亦可以在此處獨立增加AWSLambdaVPCAccessExecutionRole的權限,Role與Policies擇一即可
    "Policies": [ "AWSLambdaFullAccess" ],
    "Environment" : {
     "Variables" : {
      "AppS3Bucket" : { "Fn::If" : ["CreateS3Bucket", {"Ref":"Bucket"}, { "Ref" : "BucketName" } ] },
      //必須在此處對應實際的參數
      "ConnectionStrings" :  {"Ref":"connectionStrings"}
     }
    },
    "Events": {
     "ProxyResource": {
      "Type": "Api",
      "Properties": {
       "Path": "/{proxy+}",
       "Method": "ANY"
      }
     },
     "RootResource": {
      "Type": "Api",
      "Properties": {
       "Path": "/",
       "Method": "ANY"
      }
     }
    },
    //此處可自行加入VPC的sg及subnet,讓Lambda變成VPC內的應用程式,若不加入,則每次發行後都會被洗掉重來,另外VPCid請由後台加入
    "VpcConfig":{
     "SecurityGroupIds" : ["sg-1234567"],
     "SubnetIds" : ["subnet-1234567","subnet-4567890"]
    }
   }
  },

  "Bucket" : {
   "Type" : "AWS::S3::Bucket",
   "Condition" : "CreateS3Bucket",
   "Properties" : {
    "BucketName" : { "Fn::If" : ["BucketNameGenerated", {"Ref" : "AWS::NoValue" }, { "Ref" : "BucketName" } ] }
   }
  }
 },

 "Outputs" : {
  "ApiURL" : {
   "Description" : "API endpoint URL for Prod environment",
   "Value" : { "Fn::Sub" : "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/" }
  },
  "S3ProxyBucket" : {
   "Value" : { "Fn::If" : ["CreateS3Bucket", {"Ref":"Bucket"}, { "Ref" : "BucketName" } ] }
  }
 }
}

*.json內不允許註解,所以//必須刪除,僅供範例參考
*.VpcConfig之類的屬性名稱,很難從AWS說明文件中找到,但是可以直接去Lambda的設定檔中下載參考,所以有不知道的名稱自己先在後台設定好之後再下載SAM回來看也行。










*.如果曾替預設的Role加入AWSLambdaVPCAccessExecutionRole的權限的話,此時在serverless.template變更Role並且發行時,會引發系統想要清除預設的Role可是AWSLambdaVPCAccessExecutionRole無法刪除的錯誤,ˊ而且發行程式會卡住無法再重新發行,此時只能上後台手動將預設的Role刪除後,並且等待數分鐘後才會正常

2019年4月25日 星期四

.Net Core 部屬發佈自動取代應用程式變數 - IIS 與 AWS Lambda


.Net Core 部屬發佈自動取代應用程式變數

注意:這是以AWS Toolkit for Visual Studio的專案範本建立的專案為基礎去操作的


步驟
1.Visual Studio原生發行(限IIS)
2.Aws Visual Studio toolkit 發行至AWS Serverless or Lambda



Visual Studio原生發行 

1.建立想要的appsettings.{env.EnvironmentName}.json如appsettings.Test. json 

2.先建立發行檔(專案右鍵[發行)->依步驟到結束) 

3.打開發行檔(*.pubxml 在Properties\ PublishProfiles) 

4.增加<EnvironmentName>節點如Test 
  <PropertyGroup>
    <EnvironmentName>Test</EnvironmentName>
  </PropertyGroup>

5.直接發行後,查看程式是否有正確取得appsettings.Test. json內所設定的值 

6.自動的方式只限定IIS環境,在Linux環境上仍需要修改作業系統的環境變數。 




Aws Visual Studio toolkit 發行至AWS Serverless or Lambda
主要是透過修改serverless.template讓Parameters頁能夠增加自定義參數,以[Publish To AWS Lambda]為例。


1.打開專案內的serverless.template 

2.在Parameters的地方可以看到預設的ShouldCreateBucket與BucketName兩個設定

3.直接在此區域底下Append你要的,例如connectionStrings

4.此時回發行畫面會發現多了一個欄位,代表增加設定欄位成功


5.接著再回到serverless.template,修改Resources這個區塊

6.我們不用像上面原來一樣參考這麼多地方,只要直接修改Resources將參考對應到我們的appsettings.json的值即可

7.在發行畫面中輸入這個欄位值,測試看看是否成功。


2019年1月12日 星期六

VS2017 .Net Core 安裝 SignalR Core + 發佈到Linux上


建立專案
  1. 使用VS2017
  2. 新增專案選擇.Net Core => ASP.NET Core Web 應用程式
  3. 選擇API或Web應用程式都可
  4. 建立好之後,在專案按右鍵[加入] => [新增用戶端程式庫] => 下拉選單改成[unpkg] => 輸入 @aspnet/signalr@   接者打1或其他(目前只有1)
  5. 應該會跳出浮空的下拉選單,選最新的(但是不包含任何"預覽"的英文字樣),這樣才是正式運行版本
  6. 選取 [選擇特定檔案]、展開 [散發者/瀏覽器] 資料夾,然後選取 signalr.js 與 signalr.min.js。
  7. 將 [目標位置] 設定為 wwwroot/lib/signalr/,然後選取 [安裝]。
  8. 去寫前後端程式
  9. 前端引入<script src="~/lib/signalr/dist/browser/signalr.js"></script>

發行程式
  1. 對專案按右鍵[發行] => 部屬模式選擇[Framework依存性]或[獨立式]皆可 
  2. [Framework依存性]時[目標執行階段]保持在[可攜式];[獨立式]則指定平台(ex:Linux x64)
  3. 發行完成把資料夾壓成zip檔放著


安裝Linux
  1. 到CentOS官網下載最新版iso(https://www.centos.org/download/)
  2. 然後在虛擬機器上安裝它
  3. 從Console登入(廢話...)
  4. 設定網卡,找出剛才安裝時的網卡名稱 => cd /etc/sysconfig/network-scripts/
  5. 修改網卡, => vi {網卡名稱}
    BOOTPROTO=static
    IPADDR=192.168.xxx.xxx
    GATEWAY=192.168.xxx.1
    NETWORK=192.168.xxx.0
    NETMASK=255.255.255.0
    DNS1=8.8.8.8
  6. 輸入[ESC]結束修改模式,然後輸入;wq 存檔後離開 
  7. 停用網卡 => ifdown {網卡名稱}
  8. 啟用網卡 => ifup {網卡名稱}
  9. 測試遠端連線是否成功


下載mRemoteNG(https://mremoteng.org/download)
  1. 從遠端登入它(再度廢話...)
  2. 透過SSH工具上傳剛才的zip


在Linux上安裝.Net Core Runtime
  1. 取得package資訊 ,輸入
    sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
  2. 安裝指定版本(例如core 2.1)
    sudo yum install aspnetcore-runtime-2.1


執行.Net Core
  1. cd到放zip的那資料夾裡面
  2. 解開zip檔 => unzip {檔名}
  3. cd 到解壓的資料夾
  4. 執行dotnet指令
    sudo dotnet xxx.dll --server.urls http://192.168.xxx.xxx
    *. xxx.dll依照你專案的發行名稱輸入
    *. --server.urls可以指定運行時的ip跟port

從其他電腦測試站台失敗時
  1. 開啟防火牆
    firewall-cmd --zone=public --add-port=80/tcp --permanent
  2. 重載入防火牆
    firewall-cmd --reload

結語:對不熟linux的人而言,很麻煩。

參考網站