[{"data":1,"prerenderedAt":610},["ShallowReactive",2],{"article-string-comparisons":3},{"article":4,"tags":171,"previous":199,"next":265},{"id":5,"title":6,"author":7,"body":8,"createdAt":159,"description":160,"extension":161,"img":162,"meta":163,"navigation":122,"path":164,"seo":165,"stem":166,"tags":167,"updatedAt":159,"__hash__":170},"articles\u002Farticles\u002Fstring-comparisons.md","String Comparisons",null,{"type":9,"value":10,"toc":157},"minimark",[11,15,20,28,32,39,43,49,53,59,63,69,73,83,86,100,141,153],[12,13,14],"p",{},"In .NET there are 6 ways to compare strings.  Really? Why is it so difficult?",[16,17,19],"h4",{"id":18},"ordinal","Ordinal",[12,21,22,23,27],{},"Performs a simple byte comparison that is independent of language. This is most appropriate when comparing strings that are generated programmatically or ",[24,25,26],"strong",{},"when comparing case-sensitive resources"," such as passwords.",[16,29,31],{"id":30},"ordinalignorecase","OrdinalIgnoreCase",[12,33,34,35,38],{},"Treats the characters in the strings to compare as if they were converted to uppercase using the conventions of the invariant culture, and then performs a simple byte comparison that is independent of language. This is most appropriate when comparing strings that are generated programmatically or when",[24,36,37],{}," comparing case-insensitive resources such as paths and filenames",".",[16,40,42],{"id":41},"invariantculture","InvariantCulture",[12,44,45,46,38],{},"Compares strings in a linguistically relevant manner, but it is not suitable for display in any particular culture. Its",[24,47,48],{}," major application is to order strings in a way that will be identical across cultures",[16,50,52],{"id":51},"invariantcultureignorecase","InvariantCultureIgnoreCase",[12,54,55,56,38],{},"Compares strings in a linguistically relevant manner that ignores case, but it is not suitable for display in any particular culture. Its major application is to ",[24,57,58],{},"order strings in a way that will be identical across cultures",[16,60,62],{"id":61},"currentculture","CurrentCulture",[12,64,65,66],{},"Can be used when strings are linguistically relevant. For example, if strings are displayed to the user, or if strings are the result of user interaction,",[24,67,68],{}," culture-sensitive string comparison should be used to order the string data.",[16,70,72],{"id":71},"currentcultureignorecase","CurrentCultureIgnoreCase",[12,74,75,76,38,79,82],{},"Can be used when strings are linguistically relevant but their case is not. For example, if strings are displayed to the user but case is unimportant, culture-sensitive, ",[24,77,78],{},"case-insensitive string comparison should be used to order the string data",[80,81],"br",{},"\nTip: You should always specify explicitly the comparer as the default value is not consistent.",[12,84,85],{},"For instance,",[12,87,88,92,93,96,97,99],{},[89,90,91],"code",{},"string.IndexOf"," uses the current culture whereas ",[89,94,95],{},"string.Equals"," uses Ordinal.",[80,98],{},"\ni.e.",[101,102,107],"pre",{"className":103,"code":104,"language":105,"meta":106,"style":106},"language-cs shiki shiki-themes github-light github-dark","string.Equals(\"\", \"\", StringComparison.Ordinal); \n\nnew [] { \"\" }.Contains(\"\", StringComparer.Ordinal); \n\nnew Dictionary(StringComparer.Ordinal); \n\n","cs","",[89,108,109,117,124,130,135],{"__ignoreMap":106},[110,111,114],"span",{"class":112,"line":113},"line",1,[110,115,116],{},"string.Equals(\"\", \"\", StringComparison.Ordinal); \n",[110,118,120],{"class":112,"line":119},2,[110,121,123],{"emptyLinePlaceholder":122},true,"\n",[110,125,127],{"class":112,"line":126},3,[110,128,129],{},"new [] { \"\" }.Contains(\"\", StringComparer.Ordinal); \n",[110,131,133],{"class":112,"line":132},4,[110,134,123],{"emptyLinePlaceholder":122},[110,136,138],{"class":112,"line":137},5,[110,139,140],{},"new Dictionary(StringComparer.Ordinal);\n",[12,142,143,144,152],{},"Refer to ",[145,146,151],"a",{"href":147,"target":148,"rel":149},"https:\u002F\u002Fwww.meziantou.net\u002Fstring-comparisons-are-harder-than-it-seems.htm","_blank",[150],"noopener","blog"," for additional samples and Rosyln analyzer to help with coding within your IDE.",[154,155,156],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":106,"searchDepth":119,"depth":119,"links":158},[],"2019-12-10T17:37:51.332Z","Yes! There really are 6 ways to compare strings within .NET (I suspect other languages as well).  Hopefully this will shed some light on the options.","md","\u002Farticles\u002Fimages\u002FgzWyiS6VDt.png",{},"\u002Farticles\u002Fstring-comparisons",{"title":6,"description":160},"articles\u002Fstring-comparisons",[168,169],"netcore","sql","Ib87YXw71UKKaBTOHX5m6SHBrTG_PcVtHJ-LK6igPl0",[172,186],{"id":173,"title":174,"body":175,"description":179,"extension":161,"img":180,"meta":181,"name":168,"navigation":122,"path":182,"seo":183,"stem":184,"__hash__":185},"tags\u002Ftags\u002Fnetcore.md","Netcore",{"type":9,"value":176,"toc":177},[],{"title":106,"searchDepth":119,"depth":119,"links":178},[],".NET Core is a new version of .NET Framework, which is a free, open-source, general-purpose development platform maintained by Microsoft. It is a cross-platform framework that runs on Windows, macOS, and Linux operating systems.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1598313183973-4effcded8d5e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=675&q=80",{},"\u002Ftags\u002Fnetcore",{"description":179},"tags\u002Fnetcore","D5BWCPpKVXJTUKU0TRuD3sWQ9rXtqETGkxzHAK__g5w",{"id":187,"title":188,"body":189,"description":193,"extension":161,"img":180,"meta":194,"name":169,"navigation":122,"path":195,"seo":196,"stem":197,"__hash__":198},"tags\u002Ftags\u002Fsql.md","Sql",{"type":9,"value":190,"toc":191},[],{"title":106,"searchDepth":119,"depth":119,"links":192},[],"SQL is a standard language designed for managing data in relational database management system. SQL stands for Structured Query Language. SQL is a standard programming language specifically designed for storing, retrieving, managing or manipulating the data inside a relational database management system (RDBMS).",{},"\u002Ftags\u002Fsql",{"description":193},"tags\u002Fsql","HleFpAIKGUPMxp855dHtmfuv32MNyIbaOTi0ZjW_I1k",{"id":200,"title":201,"author":7,"body":202,"createdAt":257,"description":258,"extension":161,"img":7,"meta":259,"navigation":122,"path":260,"seo":261,"stem":262,"tags":263,"updatedAt":257,"__hash__":264},"articles\u002Farticles\u002Fdatetimeoffset-confusion.md","DateTimeOffset Confusion",{"type":9,"value":203,"toc":255},[204,216,223,226,233,236,252],[12,205,206,207,38,210,212,213,215],{},"Consider the following timestamp: ",[24,208,209],{},"1995-07-14T13:05:00.0000000-03:00",[80,211],{},"\nWhen asked what the -03:00 at the end is called, many developers answer, “a time zone.”",[80,214],{},"\nWell…",[12,217,218,219,222],{},"The -03:00 does represent the offset from UTC.\nTo get the UTC time, ",[24,220,221],{},"invert"," the offset sign then add it to the time such as 13:05 + 3 = 16:05 in UTC.",[12,224,225],{},"Okay, following this ok now more details..",[12,227,228,229,232],{},"The ",[24,230,231],{},"mistake ","is in thinking that the offset is all there is to a time zone. Nope.",[12,234,235],{},"A time zone is a geographical area, and it consists of many pieces of information, such as",[237,238,239,243,246,249],"ul",{},[240,241,242],"li",{},"One or more offsets. (DST is a thing, after all.)",[240,244,245],{},"The dates when DST transitions happen. (These can and do change whenever governments feel like it.)",[240,247,248],{},"The amount of time applied when transitions happened. (It’s not one hour everywhere.)",[240,250,251],{},"The historical records of changes to the above rules.",[12,253,254],{},"In short, is is not possible to establish the time zone by the offset!",{"title":106,"searchDepth":119,"depth":119,"links":256},[],"2019-12-11T14:02:13.400Z","For many years, dates, times, time zones, new language date types such as datetimeoffset have confused developers.  I am writing this in hopes that you can refresh some details about the often used datetimeoffset type.",{},"\u002Farticles\u002Fdatetimeoffset-confusion",{"title":201,"description":258},"articles\u002Fdatetimeoffset-confusion",[168],"zG8xVy_DOEaTRfDorK1eSmB3Hsgh4_eKm67fJnLbiak",{"id":266,"title":267,"author":7,"body":268,"createdAt":602,"description":603,"extension":161,"img":313,"meta":604,"navigation":122,"path":605,"seo":606,"stem":607,"tags":608,"updatedAt":602,"__hash__":609},"articles\u002Farticles\u002Faspnet-core-3-things-i-learned-pro-tips-migration-to-aspnet-core-3.md","ASP.NET Core 3 Things I Learned \u002F Pro Tips \u002F Migration to ASP.NET Core 3",{"type":9,"value":269,"toc":600},[270,302,317,325,328,440,455,461,486,509,514,519,533,598],[237,271,272,278,281,284,287,290,293,296,299],{},[240,273,274,275],{},"Starting up the web application with ",[24,276,277],{},"dotnet run",[240,279,280],{},"there are CLI parameters that you can use to set environment, port etc.",[240,282,283],{},"uses Kestrel to host the application",[240,285,286],{},"windows authentication cannot be turned on with dotnet run",[240,288,289],{},"can configure default behavior from within Visual Studio project properties",[240,291,292],{},"Debug, select Launch “Project” then you can set the App Url, default page, etc.",[240,294,295],{},"Hitting debug F5 within Visual Studio when the {Project Name} profile is selected hosts the application on Kestrel similar to dotnet run",[240,297,298],{},"dotnet run –e development will set the environment variable to ‘production’ (",[240,300,301],{},"in the following image you can see that I set the default environment for Kestrel runs to Development",[12,303,304,305],{},"ASPNETCORE_ENVIRONMENT Development\n",[145,306,308],{"href":307},"\u002Farticles\u002Fimages\u002Fimage_637115214952391737.png",[309,310],"img",{"style":311,"title":312,"src":313,"alt":312,"width":314,"height":315,"border":316},"border: 0px currentcolor; display: inline; background-image: none;","image","\u002Farticles\u002Fimages\u002Fimage_thumb_637115214953620084.png",545,336,0,[237,318,319,322],{},[240,320,321],{},"JSON properties are now lower case in asp.net core (i.e. when return json from a method Json({object here}) would have all properties changed to lower case)",[240,323,324],{},"use the following code to avoid camel case names by default \nservices.AddControllersWithViews()\n       .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());",[12,326,327],{},"{\"Id\":9000,\"FullName\":\"John Smith\"} would be serialized to {\"id\":9000,\"fullName\":\"John Smith\"}       ",[237,329,330,339,342,349,407,424,433],{},[240,331,332,333,338],{},"Debug ASP.NET Core apps in Visual Studio IIS\u002FIISExpress etc. reference ",[145,334,337],{"href":335,"target":148,"rel":336},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fvisualstudio\u002Fdebugger\u002Fhow-to-enable-debugging-for-aspnet-applications?view=vs-2019",[150],"here","        ",[240,340,341],{},"After setting a application within IIS, setting authentication to windows, selecting application pool with no managed code – you may get the following…\nThe in process request handler, Microsoft.AspNetCore.Server.IIS, was not referenced in the application.",[240,343,344],{},[145,345,348],{"href":346,"target":148,"rel":347},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fhost-and-deploy\u002Fiis\u002F?view=aspnetcore-2.2",[150],"Host ASP.NET Core on Windows with IIS",[240,350,351,352,355,359],{},"In order to ready http request bodies in a synchronous manner I had to add following service configuration\n",[145,353],{"href":354},"https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F47735133\u002Fasp-net-core-synchronous-operations-are-disallowed-call-writeasync-or-set-all",[145,356,354],{"href":354,"rel":357},[358],"nofollow",[101,360,362],{"className":103,"code":361,"language":105,"meta":106,"style":106},"\u002F\u002F If using Kestrel: \n\u002F\u002Fservices.Configure&lt;KestrelServerOptions>(options => \n\u002F\u002F{ \n\u002F\u002Foptions.AllowSynchronousIO = true; \n\u002F\u002F});\n\u002F\u002F If using IIS: \nservices.Configure > IISServerOptions>(options => { \noptions.AllowSynchronousIO = true; })  \n",[89,363,364,369,374,379,384,389,395,401],{"__ignoreMap":106},[110,365,366],{"class":112,"line":113},[110,367,368],{},"\u002F\u002F If using Kestrel: \n",[110,370,371],{"class":112,"line":119},[110,372,373],{},"\u002F\u002Fservices.Configure&lt;KestrelServerOptions>(options => \n",[110,375,376],{"class":112,"line":126},[110,377,378],{},"\u002F\u002F{ \n",[110,380,381],{"class":112,"line":132},[110,382,383],{},"\u002F\u002Foptions.AllowSynchronousIO = true; \n",[110,385,386],{"class":112,"line":137},[110,387,388],{},"\u002F\u002F});\n",[110,390,392],{"class":112,"line":391},6,[110,393,394],{},"\u002F\u002F If using IIS: \n",[110,396,398],{"class":112,"line":397},7,[110,399,400],{},"services.Configure > IISServerOptions>(options => { \n",[110,402,404],{"class":112,"line":403},8,[110,405,406],{},"options.AllowSynchronousIO = true; })\n",[240,408,409,410,415,416],{},"dotnet – info Shows what versions are installed on your workstation (",[145,411,414],{"href":412,"target":148,"rel":413},"https:\u002F\u002Fweblog.west-wind.com\u002Fposts\u002F2018\u002FJun\u002F05\u002FWhich-NET-Core-Runtime-Download-do-you-need",[150],"Reference Rick Strahl",")\n",[145,417,419],{"href":418},"\u002Farticles\u002Fimages\u002Fimage_637115214954889487.png",[309,420],{"style":311,"title":312,"src":421,"alt":312,"width":422,"height":423,"border":316},"\u002Farticles\u002Fimages\u002Fimage_thumb_637115214956154680.png",353,206,[240,425,426,427,430],{},"This looks really interesting but I have yet to install\u002Ftry it out Live Reload using dotnet watch ",[145,428],{"href":429},"https:\u002F\u002Fweblog.west-wind.com\u002Fposts\u002F2019\u002FJun\u002F03\u002FBuilding-Live-Reload-Middleware-for-ASPNET-Core",[145,431,429],{"href":429,"rel":432},[358],[240,434,435,436,439],{},"IHostBuilder vs IWebHostBuilder – ASP.NET Core is used to build http endpoints using Kestrel web server. \nIWebHostbuilder ",[24,437,438],{},"remains for backward compatibility only",", and was used to encapsulate DI, Logging and configuration.  This was used in earlier versions of ASP.NET Core 3 for http workloads.",[12,441,442,443,448,449,454],{},"The default .NET Core 3 ASP.NET Core template sets up by default in the program.cs IHostBuilder, which is the ",[145,444,447],{"href":445,"target":148,"rel":446},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fhost\u002Fweb-host?view=aspnetcore-3.1",[150],"recommended"," for all app types.  Documentation can be found at ",[145,450,453],{"href":451,"target":148,"rel":452},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fhost\u002Fgeneric-host?view=aspnetcore-3.1",[150],"docs.microsoft.com",".  A host can encapsulates dependency injection, logging, configuration, IHostedService implementations.  Hosting is no longer bound to Kestrel and no longer bound to ASP.NET Core (oddly, this means you can start a host that doesn’t require Kestrel and doesn’t even need the ASP.NET Core Framework)",[12,456,457,460],{},[24,458,459],{},"CreateHostBuilder"," has the following defaults",[237,462,463,475,478],{},[240,464,465,466,470,471,38],{},"Sets the ",[145,467,469],{"href":468},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Findex?view=aspnetcore-3.1#content-root","content root"," to the path returned by ",[145,472,474],{"href":473},"https:\u002F\u002Fdocs.microsoft.com\u002Fdotnet\u002Fapi\u002Fsystem.io.directory.getcurrentdirectory","GetCurrentDirectory",[240,476,477],{},"Loads host configuration from:\n----- Environment variables prefixed with \"DOTNET_\".\n----- Command-line arguments.",[240,479,480,481,485],{},"Loads app configuration from:\n----- appsettings.json.\n----- appsettings.{Environment}.json.\n----- ",[145,482,484],{"href":483},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fsecurity\u002Fapp-secrets?view=aspnetcore-3.1","Secret Manager"," when the app runs in the Development environment.\n----- Environment variables.\n----- Command-line arguments.",[237,487,488,496],{},[240,489,490,491,495],{},"Adds the following ",[145,492,494],{"href":493},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Flogging\u002Findex?view=aspnetcore-3.1","logging"," providers:\n----- Console\n----- Debug\n----- EventSource\n----- EventLog (only when running on Windows)",[240,497,498,499,503,504,508],{},"Enables ",[145,500,502],{"href":501},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fdependency-injection?view=aspnetcore-3.1#scope-validation","scope validation"," and ",[145,505,507],{"href":506},"https:\u002F\u002Fdocs.microsoft.com\u002Fdotnet\u002Fapi\u002Fmicrosoft.extensions.dependencyinjection.serviceprovideroptions.validateonbuild#Microsoft_Extensions_DependencyInjection_ServiceProviderOptions_ValidateOnBuild","dependency validation"," when the environment is Development.",[12,510,511],{},[24,512,513],{},"ConfigureWebHostDefaults ",[237,515,516],{},[240,517,518],{},"Loads host configuration from environment variables prefixed with \"ASPNETCORE_\".",[237,520,521],{},[240,522,523,524,528,529,38],{},"Sets ",[145,525,527],{"href":526},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fservers\u002Fkestrel?view=aspnetcore-3.1","Kestrel"," server as the web server and configures it using the app's hosting configuration providers. For the Kestrel server's default options, see ",[145,530,532],{"href":531},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fservers\u002Fkestrel?view=aspnetcore-3.1#kestrel-options","Kestrel web server implementation in ASP.NET Core",[237,534,535,542,549,555,563,569,572,581,590],{},[240,536,537,538,38],{},"Adds ",[145,539,541],{"href":540},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fservers\u002Fkestrel?view=aspnetcore-3.1#host-filtering","Host Filtering middleware",[240,543,537,544,548],{},[145,545,547],{"href":546},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fhost-and-deploy\u002Fproxy-load-balancer?view=aspnetcore-3.1#forwarded-headers","Forwarded Headers middleware"," if ASPNETCORE_FORWARDEDHEADERS_ENABLED=true.",[240,550,551,552,38],{},"Enables IIS integration. For the IIS default options, see ",[145,553,348],{"href":554},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Fhost-and-deploy\u002Fiis\u002Findex?view=aspnetcore-3.1#iis-options",[240,556,557,558,562],{},"Configuration for Framework-provided services can be found ",[145,559,337],{"href":560,"target":148,"rel":561},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Faspnet\u002Fcore\u002Ffundamentals\u002Fhost\u002Fgeneric-host?view=aspnetcore-3.1#framework-provided-services",[150]," (any host lifetime, environment etc.)",[240,564,565,566],{},"Unable to resolve service for type 'Microsoft.Extensions.Logging.ILoggerFactory' while attempting to activate 'Web.Startup'. – ",[24,567,568],{},"Exception\n",[240,570,571],{},"the startup constructor use to look like public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)",[240,573,574,575,580],{},"new to ASP.NET Core 3 it is no longer possible to inject ILogger in Startup.cs and Program.cs (Reference: ",[145,576,579],{"href":577,"target":148,"rel":578},"https:\u002F\u002Fgithub.com\u002Faspnet\u002FAnnouncements\u002Fissues\u002F353",[150],"Github",")",[240,582,583,584,589],{},"Another ",[145,585,588],{"href":586,"target":148,"rel":587},"https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fazure\u002Fazure-monitor\u002Fapp\u002Filogger#capture-ilogger-logs-from-startupcs-and-programcs-in-aspnet-core-apps",[150],"reference"," to this change specifically calls this out",[240,591,592,593],{},"Changes with ASP.NET Core 3 to Program.cs \u002F Startup.cs\nReference: ",[145,594,597],{"href":595,"target":148,"rel":596},"https:\u002F\u002Fandrewlock.net\u002Fexploring-the-new-project-file-program-and-the-generic-host-in-asp-net-core-3\u002F",[150],"Andrew Lock",[154,599,156],{},{"title":106,"searchDepth":119,"depth":119,"links":601},[],"2019-12-09T20:51:35.746Z","Moving from ASP.NET Core 2 to ASP.NET 3 (Migration) there were a number of 'things' I picked up and decided I would document as I moved through the application.  New Program.cs and Startup.cs changes, new logging configuration changes, and default ASP.NET Core tips included.",{},"\u002Farticles\u002Faspnet-core-3-things-i-learned-pro-tips-migration-to-aspnet-core-3",{"title":267,"description":603},"articles\u002Faspnet-core-3-things-i-learned-pro-tips-migration-to-aspnet-core-3",[168],"w0iFgfavvdV8-1UR0gCTw4qVYXmyAzFa1CYkep7Rz8M",1781574765136]