希格工作室

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刪除後,並且等待數分鐘後才會正常