tag:blogger.com,1999:blog-52296735384707301992024-03-05T11:30:08.277-05:00Six Foot CoderConnecting the developer community through conferences, user groups and training.Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.comBlogger75125tag:blogger.com,1999:blog-5229673538470730199.post-48947362705882265932024-02-09T10:45:00.001-05:002024-02-09T10:45:37.991-05:00Cleanup Local Git Branches<p> Below is a Powershell script that will remove local Git branches except for a list of excluded branches.</p><p><br /></p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;"># Usage: .\RemoveGitBranches.ps1 -directoryPath "C:\path\to\your\repository"</span></div><div><span style="color: #c586c0;">param</span> (</div><div> [<span style="color: #569cd6;">string</span>]<span style="color: #9cdcfe;">$directoryPath</span></div><div>)</div><br /><div><span style="color: #6a9955;"># Define the branches to keep</span></div><div><span style="color: #9cdcfe;">$branchesToKeep</span> = <span style="color: #569cd6;">@</span>(<span style="color: #ce9178;">"dev"</span>, <span style="color: #ce9178;">"develop"</span>, <span style="color: #ce9178;">"development"</span>, <span style="color: #ce9178;">"main"</span>, <span style="color: #ce9178;">"master"</span>, <span style="color: #ce9178;">"qa"</span>, <span style="color: #ce9178;">"test"</span>, <span style="color: #ce9178;">"stage"</span>)</div><br /><div><span style="color: #6a9955;"># Change to the specified directory</span></div><div><span style="color: #dcdcaa;">Set-Location</span> -Path <span style="color: #9cdcfe;">$directoryPath</span></div><br /><div><span style="color: #6a9955;"># Get a list of all local branches</span></div><div><span style="color: #9cdcfe;">$branches</span> = git branch --format <span style="color: #ce9178;">"%(refname:short)"</span></div><br /><div><span style="color: #c586c0;">foreach</span> (<span style="color: #9cdcfe;">$branch</span> <span style="color: #c586c0;">in</span> <span style="color: #9cdcfe;">$branches</span>) {</div><div> <span style="color: #9cdcfe;">$branch</span> = <span style="color: #9cdcfe;">$branch</span><span style="color: #dcdcaa;">.Trim</span>()</div><br /><div> <span style="color: #6a9955;"># Check if the branch is not in the list of branches to keep</span></div><div> <span style="color: #c586c0;">if</span> (<span style="color: #9cdcfe;">$branch</span> -notin <span style="color: #9cdcfe;">$branchesToKeep</span>) {</div><div> <span style="color: #6a9955;"># Delete the branch</span></div><div> git branch -D <span style="color: #9cdcfe;">$branch</span></div><div> }</div><div>}</div><br /></div>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-35493635694296714682023-12-29T16:35:00.001-05:002023-12-29T16:35:07.395-05:00Using MOQ<p>MOQ is a popular mocking framework for .NET used to create mock objects for testing. MOQ allows you to isolate the class under test by replacing its dependencies with controlled mock objects, making it easier to test behavior in isolation. Here are the steps to use it. </p><p>1. <b>Install MOQ</b>. Add MOQ using the NuGet package manager. https://www.nuget.org/packages/Moq</p><p>2. <b>Create a Mock Object.</b> Use Mock<T> where T is the type you want to mock. For example:</p><p><span style="font-family: courier;"><b>_webAPIClientMock = new Mock<IWebAPIClient>();</b></span></p><p>3, <b>Setup Method Behavior.</b> Define how the mock object should behave. For example:</p><p><span style="font-family: courier;"><span style="white-space: normal;">_webAPIClientMock.Setup(client => client.GetApplicationSetting(It.IsAny<GetAppSettingRequest>()).Result).Returns(appSettingResponse);</span></span></p><p>4. <b>Inject the mock.</b> Inject the mock object into the class you are testing.</p><p><span style="font-family: courier;">_apiSettingsProvider = new ApiSettingsProvider(Mock.Of<ILogger<ApiSettingsProvider>>(), _webAPIClientMock.Object);</span></p><p>5. <b>Verify Interactions. </b>Optionally, verify that certain interactions with the mock object occurred, like _webAPIClientMock.Verify(x => x.GetApplicationSetting(), Times.Once);</p><p>6. <b>Run Your Test. </b> Execute your test method as usual.</p><p></p><h3 style="text-align: left;">Full Example</h3><p></p><div><span style="font-family: courier;">[TestClass]<br /></span><span style="font-family: courier;">public class ApiSettingsProviderTests<br /></span><span style="font-family: courier;">{<br /></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>private Mock<IWebAPIClient> _webAPIClientMock;<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>private ApiSettingsProvider _apiSettingsProvider;<br /></span></span></div><div><span style="white-space: normal;"><span style="font-family: courier;"><br /></span></span></div><div><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>[TestInitialize]<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>public void Initialize()<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>{<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span> _webAPIClientMock = new Mock<IWebAPIClient>();<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span> _apiSettingsProvider = new ApiSettingsProvider(Mock.Of<ILogger<ApiSettingsProvider>>(), _webAPIClientMock.Object);<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>}</span></span></div><div><span style="white-space: normal;"><span style="font-family: courier;"><br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>[TestMethod]<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>public void GetAppSettingValue_ShouldReturnFirstValueFromAppSettingsResponse()<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>{<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span> // Arrange<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>var appSettingName = "TestSetting";<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>var settingValues = new string[] { "Value1", "Value2" };<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>var appSettingResponse = new GetAppSettingResponse<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>{<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>SettingValues = new List<string>(settingValues)<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>};</span></span><span style="font-family: courier;"><br /></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>_webAPIClientMock.Setup(client => client.GetApplicationSetting(It.IsAny<GetAppSettingRequest>()).Result).Returns(appSettingResponse);</span></span><span style="font-family: courier;"><br /></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>// Act<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>var value = _apiSettingsProvider.GetAppSettingValue(appSettingName);</span></span><span style="font-family: courier;"><br /></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>// Assert<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>Assert.AreEqual("Value1", value);<br /></span></span><span style="white-space: normal;"><span style="font-family: courier;"><span style="white-space: pre;"> </span>}<br /></span></span><span style="font-family: courier;">}</span></div><h3 style="text-align: left;"><span style="font-family: inherit;">Resources</span></h3><div><a href="https://sixfootcoder.blogspot.com/2017/03/moq-resources.html">https://sixfootcoder.blogspot.com/2017/03/moq-resources.html</a></div>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-40512596718956776392023-12-29T16:06:00.000-05:002023-12-29T16:06:07.925-05:00Creating Angular Tests and Mocking with Jasmine<p>When creating Angular Components, by default a spec.ts file is created. By definition, a unit test should not call any files, databases, or services. We use a mock, or a stand in for services. </p><h3 style="text-align: left;">Mocking Services</h3><p>To mock services, the jasmine.createSpyObj is used. Example:</p><p><span style="font-family: courier;">loggingService = jasmine.createSpyObj('LoggingService', ['Info','Error']);</span> </p><h3 style="text-align: left;">Providing Mocked Services</h3><p>To use the mocked service, it is provied. Example:</p><p><span style="font-family: courier;"> TestBed.configureTestingModule({<br /></span><span style="font-family: courier;"> providers: [<br /></span><span style="font-family: courier;"> ErrorHandlerService, <br /></span><span style="font-family: courier;"> { provide: LoggingService, useValue: loggingService },<br /></span><span style="font-family: courier;"> { provide: HttpTestingController, useValue: httpTestingController }<br /></span><span style="font-family: courier;"> ],<br /></span><span style="font-family: courier;"> });</span></p><p><br /></p><h3 style="text-align: left;">Full Example</h3><p>We have an error handler service and we want to ensure that the message is logged by using the Error method.</p><div><span style="font-family: courier;">import { TestBed } from '@angular/core/testing';<br /></span><span style="font-family: courier;">import { HttpErrorResponse } from '@angular/common/http';<br /></span><span style="font-family: courier;">import { ErrorHandlerService } from './error-handler.service';<br /></span><span style="font-family: courier;">import { LoggingService } from './logging.service';<br /></span><span style="font-family: courier;">import { HttpTestingController } from '@angular/common/http/testing';</span></div><div><span style="font-family: courier;"><br /></span><span style="font-family: courier;">describe('ErrorHandlerService', () => {<br /></span><span style="font-family: courier;"> let errorHandlerService: ErrorHandlerService;<br /></span><span style="font-family: courier;"> let loggingService: LoggingService;<br /></span><span style="font-family: courier;"> let httpTestingController: HttpTestingController;<br /></span><span style="font-family: courier;"> <br /></span><span style="font-family: courier;"> beforeEach(() => {<br /></span><span style="font-family: courier;"> loggingService = jasmine.createSpyObj('LoggingService', ['Info','Error']);</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> TestBed.configureTestingModule({<br /></span><span style="font-family: courier;"> providers: [<br /></span><span style="font-family: courier;"> ErrorHandlerService, <br /></span><span style="font-family: courier;"> { provide: LoggingService, useValue: loggingService },<br /></span><span style="font-family: courier;"> { provide: HttpTestingController, useValue: httpTestingController }<br /></span><span style="font-family: courier;"> ],<br /></span><span style="font-family: courier;"> });</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> errorHandlerService = TestBed.inject(ErrorHandlerService);<br /></span><span style="font-family: courier;"> httpTestingController = TestBed.inject(HttpTestingController);<br /></span><span style="font-family: courier;"> });</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> it('should be created', () => {<br /></span><span style="font-family: courier;"> expect(errorHandlerService).toBeTruthy();<br /></span><span style="font-family: courier;"> });</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> it('should handle an error and log it', () => {<br /></span><span style="font-family: courier;"> spyOn(console, 'error');</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> const error = new Error('Test error message');</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> errorHandlerService.handleError(error);</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> expect(console.error).toHaveBeenCalledWith(error);<br /></span><span style="font-family: courier;"> expect(loggingService.Error).toHaveBeenCalledWith(error.message, [error]);<br /></span><span style="font-family: courier;"> });</span><span style="font-family: courier;"><br /></span><span style="font-family: courier;"> <br /></span><span style="font-family: courier;">});</span></div><div style="text-align: left;"><br /></div><p><br /></p><p><br /></p>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-13038854050477960262023-10-05T07:47:00.004-04:002023-10-09T08:45:26.690-04:00Angular with .NET Core Powershell Setup Script<p>Here is a Powershell script that I made to automatically install everything that is needed to develop with Angular 16 and .NET Core 7.</p><p>Here's a breakdown:</p><p><br /></p><p>1. <b>Chocolatey Installation Check</b>: At the beginning, the script checks if Chocolatey, a package manager for Windows, is already installed. If it is found at the specified location (`C:\ProgramData\chocolatey`), it prints a message indicating that Chocolatey is installed. If it is not found, the script adjusts the execution policy to allow the script to run, then it fetches and executes the installation script for Chocolatey from its official website.</p><p>2. <b>API Software Installation</b>: Through the Chocolatey package manager, the script proceeds to install the .NET 7.0 SDK, Visual Studio 2022 Community edition, web and data workloads for Visual Studio 2022, SQL Server Management Studio, and Postman. The flags `-y`, `--allow-empty-checksums`, and `--ignore-checksum` are used to automatically approve installations and bypass checksum verifications, which are useful in automated environments but can present security risks if the sources are not trusted.</p><p>3. <b>UI Software Installation</b>: For front-end or user interface development, the script installs Node.js LTS version and Visual Studio Code (VSCode) using Chocolatey.</p><p>4. <b>VS Code Extensions Installation</b>: Once VSCode is installed, the script installs a series of extensions for it. These extensions range from linters like ESLint, support for Angular development, CSS formatting tools, IntelliSense for paths and classes, and other utility extensions like auto-rename tags, icons, Prettier formatter, and GitHub's Copilot and Copilot Chat.</p><p>5. <b>Angular CLI Installation</b>: Finally, the script installs the Angular Command-Line Interface (CLI) globally using npm, the Node.js package manager. The Angular CLI is a vital tool for Angular developers, allowing them to create, manage, and deploy Angular applications with ease.</p><p>In summary, this script serves as a one-stop solution to set up a development environment with all the necessary tools and extensions for both API and UI development, primarily targeting .NET and Angular technologies.</p><p><br /></p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #6a9955;"># Install Chocolatey if it does not exist</span></div><div><span style="color: #c586c0;">if</span> (<span style="color: #dcdcaa;">Test-Path</span> <span style="color: #ce9178;">'C:\ProgramData\chocolatey'</span>) {</div><div> <span style="color: #dcdcaa;">Write-Host</span> <span style="color: #ce9178;">"Chocolatey is installed."</span></div><div>} <span style="color: #c586c0;">else</span> {</div><div> <span style="color: #dcdcaa;">Set-ExecutionPolicy</span> Bypass -Scope <span style="color: #c586c0;">Process</span> -Force; [<span style="color: #569cd6;">System.Net.ServicePointManager</span>]::SecurityProtocol = [<span style="color: #569cd6;">System.Net.ServicePointManager</span>]::SecurityProtocol -bor <span style="color: #b5cea8;">3072</span>; iex ((<span style="color: #dcdcaa;">New-Object</span> System.Net.WebClient).DownloadString(<span style="color: #ce9178;">'https://community.chocolatey.org/install.ps1'</span>))</div><div>}</div><br /><div><span style="color: #6a9955;"># API Software</span></div><div>& choco install dotnet-<span style="color: #b5cea8;">7.0</span>-sdk -y --allow-empty-checksums --ignore-checksum</div><div>& choco install visualstudio2022community -y --allow-empty-checksums --ignore-checksum</div><div>& choco install visualstudio2022-workload-netweb -y --allow-empty-checksums --ignore-checksum</div><div>& choco install visualstudio2022-workload-data -y --allow-empty-checksums --ignore-checksum</div><div>& choco install sql-server-management-studio -y --allow-empty-checksums --ignore-checksum</div><div>& choco install postman -y --allow-empty-checksums --ignore-checksum</div><br /><div><span style="color: #6a9955;"># UI Software</span></div><div>& choco install nodejs-lts -y --allow-empty-checksums --ignore-checksum</div><div>& choco install vscode -y --allow-empty-checksums --ignore-checksum</div><br /><div><span style="color: #6a9955;"># VS Code Extensions</span></div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> dbaeumer.vscode-eslint</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> johnpapa.Angular2</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> aeschli.vscode-css-formatter</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> Angular.ng-template</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> Zignd.html-css-class-completion</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> christian-kohler.path-intellisense</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> formulahendry.auto-<span style="color: #dcdcaa;">rename-tag</span></div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> vscode-icons-team.vscode-icons</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> esbenp.prettier-vscode</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> GitHub.copilot</div><div>& <span style="color: #ce9178;">"C:\Program Files\Microsoft VS Code\bin\code"</span> --<span style="color: #dcdcaa;">install-extension</span> GitHub.copilot-chat</div><br /><div><span style="color: #6a9955;"># Install Angular CLI</span></div><div>& npm install -g <span style="color: #9cdcfe;">@angular</span>/cli</div></div>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-15181492826780098132023-10-02T09:15:00.008-04:002023-10-02T09:15:50.783-04:00Angular 16 Resources<p>There is a steep learning curve with Angular 16. Fortunately there are a lot of resources out there to ramp up.</p><h1 style="text-align: left;">Main Site</h1><p>The main site for Angular is http://angular.io. It has documentation and a quick start which are semi-useful.</p><h1 style="text-align: left;">Free YouTube Courses</h1><p></p><ul style="text-align: left;"><li>A Complete Angular Course from Scratch: <a href="https://www.youtube.com/watch?v=3BIuwVnddG0&list=PL1BztTYDF-QNlGo5-g65Xj1mINHYk_FM9">https://www.youtube.com/watch?v=3BIuwVnddG0&list=PL1BztTYDF-QNlGo5-g65Xj1mINHYk_FM9</a></li><li>Angular for Beginners Course: <a href="https://www.youtube.com/watch?v=3qBXWUpoPHo">https://www.youtube.com/watch?v=3qBXWUpoPHo</a></li><li>Angular Crash Course: <a href="https://www.youtube.com/watch?v=3dHNOWTI7H8">https://www.youtube.com/watch?v=3dHNOWTI7H8</a></li></ul><p></p><p><br /></p><h1 style="text-align: left;">Commercial Angular Course</h1><p><a href="https://www.udemy.com/course/real-world-app-angular-aspnet-core-web-api-and-sql/">https://www.udemy.com/course/real-world-app-angular-aspnet-core-web-api-and-sql/</a></p><h1 style="text-align: left;">Example Angular Project</h1><p></p><ul style="text-align: left;"><li>Angular UI: <a href="https://github.com/GregFinzer/CodePulse.UI">https://github.com/GregFinzer/CodePulse.UI</a></li><li>.NET Core 7 Web API: <a href="https://github.com/GregFinzer/CodePulse.API">https://github.com/GregFinzer/CodePulse.API</a></li></ul><div><br /></div><p></p><h1 style="text-align: left;">Quick References</h1><div><div><ul style="text-align: left;"><li><a href="https://cheatography.com/gregfinzer/cheat-sheets/angular/">https://cheatography.com/gregfinzer/cheat-sheets/angular/</a></li><li><a href="https://cheatography.com/rajanvora/cheat-sheets/angular-cheat-sheet/">https://cheatography.com/rajanvora/cheat-sheets/angular-cheat-sheet/</a></li><li><a href="https://cheatography.com/spegusess/cheat-sheets/angular/">https://cheatography.com/spegusess/cheat-sheets/angular/</a></li><li><a href="https://cheatography.com/gregfinzer/cheat-sheets/angular-cli/">https://cheatography.com/gregfinzer/cheat-sheets/angular-cli/</a></li><li><a href="https://cheatography.com/wakers01/cheat-sheets/angular-cli/">https://cheatography.com/wakers01/cheat-sheets/angular-cli/</a></li></ul></div></div>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-69310674649160434012023-09-30T07:52:00.000-04:002023-09-30T07:52:34.608-04:00Software Development Requirements for Angular<h1 style="text-align: left;">Install the LTS Version of Node</h1><p>https://nodejs.org</p><p><b>Or install with Chocolatey</b></p><p><span style="font-family: courier;">choco install nodejs-lts</span></p><p><br /></p><h1 style="text-align: left;">Install the Angular CLI</h1><p>At the command prompt</p><p><span style="font-family: courier;">npm install -g @angular/cli</span></p><p><br /></p><h1 style="text-align: left;">Install VS Code</h1><p>https://code.visualstudio.com/</p><p><b>Or install with Chocolatey</b></p><p><span style="font-family: courier;">choco install vscode</span></p><p><br /></p><h1 style="text-align: left;">Install VS Code Extensions</h1><p>ESLint: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint</p><p>Angular Snippets (Version 16): https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2</p><p>CSS Formatter: https://marketplace.visualstudio.com/items?itemName=aeschli.vscode-css-formatter</p><p>Angular Language Service: https://marketplace.visualstudio.com/items?itemName=Angular.ng-template</p><p>IntelliSense for CSS class names in HTML: https://marketplace.visualstudio.com/items?itemName=Zignd.html-css-class-completion</p><p>Path Intellisense: https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense</p><p><b>Or install on the command line:</b></p><p><span style="font-family: courier;"><br /></span></p><p><span style="font-family: courier;">"C:\Program Files\Microsoft VS Code\bin\code" --install-extension dbaeumer.vscode-eslint</span></p><p><span style="font-family: courier;">"C:\Program Files\Microsoft VS Code\bin\code" --install-extension johnpapa.Angular2</span></p><p><span style="font-family: courier;">"C:\Program Files\Microsoft VS Code\bin\code" --install-extension aeschli.vscode-css-formatter</span></p><p><span style="font-family: courier;">"C:\Program Files\Microsoft VS Code\bin\code" --install-extension Angular.ng-template</span></p><p><span style="font-family: courier;">"C:\Program Files\Microsoft VS Code\bin\code" --install-extension Zignd.html-css-class-completion</span></p><p><span style="font-family: courier;">"C:\Program Files\Microsoft VS Code\bin\code" --install-extension christian-kohler.path-intellisense</span></p>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-29956672397111285852023-09-29T10:44:00.003-04:002023-09-30T07:48:14.411-04:00Developer Software Requirements for Creating a .NET Core Web API<h1 style="text-align: left;">Install .NET 7 SDK</h1><p><a href="https://dotnet.microsoft.com/en-us/download">https://dotnet.microsoft.com/en-us/download</a></p><p><b>Or Install with Chocolatey</b></p><p><span style="font-family: courier;">choco install dotnet-7.0-sdk</span></p><h1 style="text-align: left;">Install Visual Studio 2022</h1><p><a href="https://visualstudio.microsoft.com">https://visualstudio.microsoft.com</a></p><p>Choose workloads</p><p>ASP.NET and Web Development</p><p>Data Storage and Processing</p><p><b>Or Install One of These with Chocolatey</b></p><p><span style="font-family: courier;">choco install visualstudio2022community</span></p><p><span style="font-family: courier;">choco install visualstudio2022professional</span></p><p><span style="font-family: courier;">choco install visualstudio2022enterprise</span></p><p>Then install workloads</p><p><span style="font-family: courier;">choco install visualstudio2022-workload-netweb<span style="white-space: pre;"> </span></span></p><p><span style="font-family: courier;">choco install visualstudio2022-workload-data</span></p><p><span style="font-family: courier;"><br /></span></p><h1 style="text-align: left;">Install SQL Server Developer Edition</h1><p><a href="https://www.microsoft.com/en-us/sql-server/sql-server-downloads">https://www.microsoft.com/en-us/sql-server/sql-server-downloads</a></p><p>Choose Basic</p><p><br /></p><h1 style="text-align: left;">Install SQL Server Management Studio or Database .NET</h1><h3 style="text-align: left;">SQL Server Management Studio</h3><p><a href="https://learn.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16">https://learn.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16</a></p><p><b>Or install with Chocolatey</b></p><p><span style="font-family: courier;">choco install sql-server-management-studio</span></p><p><br /></p><h3 style="text-align: left;">Database.NET</h3><p><a href="https://fishcodelib.com/database.htm">https://fishcodelib.com/database.htm</a></p><p><b>Or install with Chocolatey</b></p><p><span style="font-family: courier;">choco install databasenet</span></p><h1 style="text-align: left;"><span style="font-family: inherit;">Install Postman </span></h1><p><span style="font-family: inherit;"><a href="https://www.postman.com/downloads/">https://www.postman.com/downloads/</a></span></p><p>Or install with Chocolatey</p><p><span style="font-family: courier;">choco install postman</span></p>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-77985797167492064422023-09-28T11:29:00.001-04:002023-09-28T11:35:43.022-04:00Angular 16 CLI Resources<p> </p><h1 id="AngularCLI-Links" style="background-color: white; border-bottom-color: rgb(204, 204, 204); color: #333333; font-family: Arial, sans-serif; font-size: 24px; font-weight: normal; line-height: 1.25; margin: 0px; padding: 0px;">Links</h1><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><strong>Official Page</strong><br /><a class="external-link" href="https://cli.angular.io/" rel="nofollow" style="color: #3572b0; text-decoration-line: none;">https://cli.angular.io/</a></div><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><strong>Github page</strong><br /><a class="external-link" href="https://github.com/angular/angular-cli" rel="nofollow" style="color: #3572b0; text-decoration-line: none;">https://github.com/angular/angular-cli</a></div><div style="background-color: white; margin-top: 10px; padding: 0px;"><strong style="color: #333333; font-family: Arial, sans-serif; font-size: 14px;">Node Package Repository</strong><br /><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><a href="https://www.npmjs.com/package/@angular/cli">https://www.npmjs.com/package/@angular/cli</a></span></span></div><h1 id="AngularCLI-Usage" style="background-color: white; border-bottom-color: rgb(204, 204, 204); color: #333333; font-family: Arial, sans-serif; font-size: 24px; font-weight: normal; line-height: 1.25; margin: 30px 0px 0px; padding: 0px;">Usage</h1><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><strong>Installation</strong></div><div style="background-color: white; margin-top: 10px; padding: 0px;"><span style="color: #333333;"><span style="font-size: 14px;"><span style="font-family: Arial, sans-serif;">Install LTS version of Node: https://nodejs.org or install with Chocolatey: </span><span style="font-family: courier;">choco install nodejs-lts</span></span></span><br /><span style="color: #333333; font-family: courier;"><span style="font-size: 14px;">npm install -g @angular/cli</span></span></div><div style="background-color: white; margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><br /></span></span></div><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><strong>New Project</strong><br />ng new <project-name></div><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><strong>Generate a component</strong><br />ng generate component <component-name></div><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><div style="margin-top: 10px; padding: 0px;"><strong>Generate a service</strong><br />ng generate service <service-name></div><div><br /></div></div><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><strong>Run the server on <a class="external-link" href="http://localhost:4200/" rel="nofollow" style="color: #3572b0; text-decoration-line: none;">http://localhost:4200</a></strong><br />ng serve --open</div><h1 id="AngularCLI-Videos" style="background-color: white; border-bottom-color: rgb(204, 204, 204); color: #333333; font-family: Arial, sans-serif; font-size: 24px; font-weight: normal; line-height: 1.25; margin: 30px 0px 0px; padding: 0px;">Videos</h1><div style="background-color: white; color: #333333; font-family: Arial, sans-serif; font-size: 14px; margin-top: 10px; padding: 0px;"><div style="margin-top: 10px; padding: 0px;">Angular CLI Complete Course Guide</div><div style="margin-top: 10px; padding: 0px;"><a href="https://www.youtube.com/watch?v=iEPegoPPHDk&list=PL_euSNU_eLbfmSwZYA3ab3a3JGQk8pQdZ">https://www.youtube.com/watch?v=iEPegoPPHDk&list=PL_euSNU_eLbfmSwZYA3ab3a3JGQk8pQdZ</a></div></div><h1 id="AngularCLI-Tutorials" style="background-color: white; border-bottom-color: rgb(204, 204, 204); color: #333333; font-family: Arial, sans-serif; font-size: 24px; font-weight: normal; line-height: 1.25; margin: 30px 0px 0px; padding: 0px;">Tutorials</h1><div style="background-color: white; margin-top: 10px; padding: 0px;"><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;">Angular CLI Tutorial</span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><a href="https://www.tutorialspoint.com/angular_cli/index.htm">https://www.tutorialspoint.com/angular_cli/index.htm</a></span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><br /></span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;">Angular CLI tutorial</span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><a href="https://www.tektutorialshub.com/angular/angular-cli-tutorial/">https://www.tektutorialshub.com/angular/angular-cli-tutorial/</a></span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><br /></span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;">Getting Started With Angular Using the Angular CLI</span></span></div><div style="margin-top: 10px; padding: 0px;"><span style="color: #333333; font-family: Arial, sans-serif;"><span style="font-size: 14px;"><a href="https://www.digitalocean.com/community/tutorials/getting-started-with-angular-using-the-angular-cli">https://www.digitalocean.com/community/tutorials/getting-started-with-angular-using-the-angular-cli</a></span></span></div></div><h1 id="AngularCLI-CheatSheets" style="background-color: white; border-bottom-color: rgb(204, 204, 204); color: #333333; font-family: Arial, sans-serif; font-size: 24px; font-weight: normal; line-height: 1.25; margin: 30px 0px 0px; padding: 0px;">Cheat Sheets</h1><div style="background-color: white; margin-top: 10px; padding: 0px;"><div style="margin-top: 10px; padding: 0px;"><a href="https://cheatography.com/gregfinzer/cheat-sheets/angular-cli/">https://cheatography.com/gregfinzer/cheat-sheets/angular-cli/</a></div><div style="margin-top: 10px; padding: 0px;"><a href="https://www.cheatography.com/wakers01/cheat-sheets/angular-cli/">https://www.cheatography.com/wakers01/cheat-sheets/angular-cli/</a></div><div style="margin-top: 10px; padding: 0px;"><a href="https://cli.angular.io/reference.pdf">https://cli.angular.io/reference.pdf</a></div></div>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-5635518885683883442023-09-27T15:03:00.000-04:002023-09-27T15:03:20.808-04:00Troubleshooting Deploying Blazor to a Linux App Service in Azure<p>It all started one day when I decided to try and deploy the Bed Brigade National Website (which is a Blazor Server application) to Azure using Github actions. </p><p>The github repo is located here: <a href="https://github.com/GregFinzer/BedBrigadeNational">https://github.com/GregFinzer/BedBrigadeNational</a></p><p>Thank God for Patrick God and Tim Corey who have excellent tutorials on YouTube. Here are the videos that I followed when deploying to Azure:</p><p>Create Web App in Azure: <a href="https://www.youtube.com/watch?v=NiBEk8QepP4">https://www.youtube.com/watch?v=NiBEk8QepP4</a></p><p>Deploy Blazor with Github actions: <a href="https://www.youtube.com/watch?v=wybpWMrpuZk">https://www.youtube.com/watch?v=wybpWMrpuZk</a></p><p>Updating the Connection String in Blazor: <a href="https://www.youtube.com/watch?v=lSCjtrNkT38">https://www.youtube.com/watch?v=lSCjtrNkT38</a></p><p>Deployment is always difficult and deploying to Azure has its share of pain. Only the first exception was obvious. </p><h1 style="text-align: left;">Could not find part of the path</h1><div>I had volunteers working on the website and they were using non-standard path combination. In other words, they were making a windows platform specific path like this:</div><div><br /></div><div><span style="font-family: courier;">string directory = appRoot + "\\" + folder + "\\" + filename;</span></div><div><br /></div><div>The platform agnostic way to do this so it works under Linux:</div><div><br /></div><div><span style="font-family: courier;">string directory = Path.Combine(appRoot, folder, filename)</span></div><div><br /></div><div><br /></div><h1 style="text-align: left;">SQL Server Transient Failure</h1><div>If you are using Basic B1 and a low tier for SQL Server, get ready for a lot of retries. This is even if you have caching enabled in your application. Here is my previous post on caching: https://sixfootcoder.blogspot.com/2018/09/using-caching-in-net-framework.html</div><div><br /></div><div><br /></div><div>You will get this error message:</div><div><br /></div><div><i>An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure' to the 'UseSqlServer' call. </i></div><div><br /></div><div>In order to fix this, you have to add a line to your context factory with EnableRetryOnFailure.</div><div> </div>
<pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas, "Courier New", Courier, monospace; font-size: 10pt;">builder.Services.AddDbContextFactory<DataContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString(<span style="color: #a31515;">"DefaultConnection"</span>), sqlBuilder =>
{
sqlBuilder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), <span style="color: blue;">null</span>);
});
options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
options.UseApplicationServiceProvider(_svcProvider);
});</code></pre>
<p><br /></p><h1 style="text-align: left;">Unable to resolve service for type IResponseCompressionProvider</h1><div>Blazor Server does not support Response Compression. You might be seeing this exception:</div><div><br /><i>Unable to resolve service for type 'Microsoft.AspNetCore.ResponseCompression.IResponseCompressionProvider' while attempting to activate </i><br /><br />If you have this line in your program.cs, remove it as that is causing the error:</div><div><br /></div><div><span style="font-family: courier;">app.UseResponseCompression();</span></div><div><span style="font-family: courier;"><br /></span></div><h1 style="text-align: left;"><span style="font-family: inherit;">Could not load assembly DependencyModel</span></h1><div><span style="font-family: inherit;">There is a known issue with Serilog and Azure. You may be seeing this exception:</span></div><div><span style="font-family: inherit;"><i><br /></i></span></div><div><i>Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyModel</i></div><div><span style="font-family: inherit;"><br /></span></div><div>There are two fixes that you have to make for this:</div><div><br /></div><div><span style="font-family: inherit;">Add a reference to these NuGet packages in your client project:</span></div><div><span style="font-family: courier;">Microsoft.Extensions.DependencyInjection</span></div><div><span style="font-family: courier;">Microsoft.Extensions.DependencyModel</span></div><div><br /></div><div>If you have a tests project, go to the properties of the project. Under Application and then Packaging, uncheck: <span style="font-family: courier;">Allow publishing outside Visual Studio, such as "dotnet publish"</span></div><div><span style="font-family: courier;"><br /></span></div><h1 style="text-align: left;"><span style="font-family: inherit;">Connection Timeout Expired</span></h1><div><span style="font-family: inherit;">You might be seeing this error: </span></div><p><i>Microsoft.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=162; handshake=279; [Login] initialization=0; authentication=1; [Post-Login] complete=29565; </i></p><p>This was the worst error to deal with. I can't believe that this is a default Azure option for SQL Server but it is. SQL Server has an Auto Pause feature that if it is not used then it shuts down. Supposedly it should come back up when accessed again but it does not. There is a defect. It shuts down and stays down. </p><p>To correct this issue, click on the SQL Service then SQL Databases, then the name of your database and finally Compute + Storage. Uncheck Enable auto-pause.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOUzEQQe6MC1m-GP7zPN8tPXo9O-cWhLbk4bJHuc_dJo7Hys6C15jcO6ubxOv2jI_zyRGXH37gHfvRnONajgcEo9UMzNQZily5ZXx6PUaI5eLxGJOzW_MaNNOYOWairg_YtMxekhVNX3RC3Y5MgdzGRUOD46Yx8H6klor9AZSM-T9x_eCj5bCbqhwvD1Td/s1055/SqlAutopause.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="411" data-original-width="1055" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOUzEQQe6MC1m-GP7zPN8tPXo9O-cWhLbk4bJHuc_dJo7Hys6C15jcO6ubxOv2jI_zyRGXH37gHfvRnONajgcEo9UMzNQZily5ZXx6PUaI5eLxGJOzW_MaNNOYOWairg_YtMxekhVNX3RC3Y5MgdzGRUOD46Yx8H6klor9AZSM-T9x_eCj5bCbqhwvD1Td/s16000/SqlAutopause.png" /></a></div><br /><p><br /></p><p><br /></p><p>The other option you should do is to enable Always On for your App Service. Click on your App Service, then Configuration, then General settings, and then Always On.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCwM10tOhlyQr3OyfBTszbwSWoRQYGVSkGJP79rDcW5vBNvEq_JHGUN1u22ePk6XSnlW0T9HXVFhXsJc8ntTSzSlybz99QeRN0qUwfYqO8lj3qPSElSJwEsX_Ui10Z7m8SjNPj528coz-o_GfuMSb8T_i7UZ-Ifw0m1e3MRy1t3dVYVDwMgTCNEt_CEaHQ/s1262/AlwaysOn.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="903" data-original-width="1262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCwM10tOhlyQr3OyfBTszbwSWoRQYGVSkGJP79rDcW5vBNvEq_JHGUN1u22ePk6XSnlW0T9HXVFhXsJc8ntTSzSlybz99QeRN0qUwfYqO8lj3qPSElSJwEsX_Ui10Z7m8SjNPj528coz-o_GfuMSb8T_i7UZ-Ifw0m1e3MRy1t3dVYVDwMgTCNEt_CEaHQ/s16000/AlwaysOn.png" /></a></div><br /><p><br /></p>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-60790825385918364922023-09-27T10:56:00.000-04:002023-09-27T10:56:12.849-04:00Best Practices when using Swagger with .NET Core<p> Take your Swagger documentation to the next level by using several different configuration options:</p><p></p><ol style="text-align: left;"><li>Replace your existing AddSwaggerGen and add information about your project.</li><li>Pull your existing XML Documentation into Swagger</li><li>Use Swagger Annotations to define return types and status codes.</li></ol><h3 style="text-align: left;">Alter AddSwaggerGen</h3><div>In your program.cs of your project, replace your AddSwagerGen with the following code, altering to the needs of your project.</div><div><br /></div><pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas, "Courier New", Courier, monospace; font-size: 10pt;"><span style="color: blue;">var</span> apiInfo = <span style="color: blue;">new</span> OpenApiInfo
{
Title = <span style="color: #a31515;">"Blogs API"</span>,
Version = <span style="color: #a31515;">"v1"</span>,
Description = <span style="color: #a31515;">"An API to perform Blog operations"</span>,
TermsOfService = <span style="color: blue;">new</span> Uri(<span style="color: #a31515;">"https://example.com/terms"</span>),
Contact = <span style="color: blue;">new</span> OpenApiContact
{
Name = <span style="color: #a31515;">"John Whorfin"</span>,
Email = <span style="color: #a31515;">"John.Whorfin@gmail.com"</span>,
Url = <span style="color: blue;">new</span> Uri(<span style="color: #a31515;">"https://twitter.com/jwhorfin"</span>),
},
License = <span style="color: blue;">new</span> OpenApiLicense
{
Name = <span style="color: #a31515;">"Blog API LICX"</span>,
Url = <span style="color: blue;">new</span> Uri(<span style="color: #a31515;">"https://example.com/license"</span>),
}
};
<span style="color: blue;">var</span> securityScheme = <span style="color: blue;">new</span> OpenApiSecurityScheme
{
Name = <span style="color: #a31515;">"Authorization"</span>,
Type = SecuritySchemeType.Http,
Scheme = <span style="color: #a31515;">"bearer"</span>,
BearerFormat = <span style="color: #a31515;">"JWT"</span>,
In = ParameterLocation.Header,
Description = <span style="color: #a31515;">"JWT Authorization header using the Bearer scheme."</span>
};
<span style="color: blue;">var</span> securityRequirement = <span style="color: blue;">new</span> OpenApiSecurityRequirement
{
{
<span style="color: blue;">new</span> OpenApiSecurityScheme
{
Reference = <span style="color: blue;">new</span> OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = <span style="color: #a31515;">"Bearer"</span>
}
},
Array.Empty<<span style="color: blue;">string</span>>()
}
};
<span style="color: green;">// Register the Swagger generator, defining 1 or more Swagger documents</span>
services.AddSwaggerGen(options =>
{
options.SwaggerDoc(<span style="color: #a31515;">"v1"</span>, apiInfo);
options.AddSecurityDefinition(<span style="color: #a31515;">"Bearer"</span>, securityScheme);
options.AddSecurityRequirement(securityRequirement);
<span style="color: green;">// using System.Reflection;</span>
<span style="color: blue;">var</span> xmlFilename = $<span style="color: #a31515;">"{Assembly.GetExecutingAssembly().GetName().Name}.xml"</span>;
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});</code></pre><pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: Consolas, "Courier New", Courier, monospace; font-size: 10pt;"><br /></code></pre><pre style="background-color: white; margin: 0em; overflow: auto;"><br /></pre><h3 style="text-align: left;">Generate XML Documentation</h3><div>Open the properties file of your project. Scroll down to the Build and then Output. </div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg-Q-X4FYBmc1nnjb9Iaj9qSakMHZks1ZwusG9ZFrr8xjJk6w9rAZ1HVFdamkE9cCDsT7HIr-7Hq7SKLqKKZ8mR5otNQ2Qa25IlXMADmS0bemnBm-n206KTiNrdfD0ewTpF6mivWyCWiJlokBF0yXVABihSILTdg-U4-1KO8Mc0CDTkuRWs2PfUknDP3XG/s284/GenerateXmlDoc.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="54" data-original-width="284" height="54" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg-Q-X4FYBmc1nnjb9Iaj9qSakMHZks1ZwusG9ZFrr8xjJk6w9rAZ1HVFdamkE9cCDsT7HIr-7Hq7SKLqKKZ8mR5otNQ2Qa25IlXMADmS0bemnBm-n206KTiNrdfD0ewTpF6mivWyCWiJlokBF0yXVABihSILTdg-U4-1KO8Mc0CDTkuRWs2PfUknDP3XG/s1600/GenerateXmlDoc.png" width="284" /></a></div><br /><div><br /></div><div><h3 style="clear: both; text-align: left;">Use Swagger Annotations on a Controller</h3><div>Make sure you have a using Swashbuckle.AspNetCore.Annotations in your controller</div><div><br /></div><div><br /></div><div><br /></div>
<p></p>
<p></p>
<pre style="margin:0em; overflow:auto; background-color:#ffffff;"><code style="font-family:Consolas,"Courier New",Courier,Monospace; font-size:10pt; color:#000000;"><span style="color:#0000ff;">using</span> Swashbuckle.AspNetCore.Annotations;
[Route(<span style="color:#a31515;">"api/[controller]"</span>)]
[ApiController]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> CategoriesController : ControllerBase
{
<span style="color:#0000ff;">private</span> <span style="color:#0000ff;">readonly</span> ICategoryRepository _categoryRepository;
<span style="color:#0000ff;">public</span> CategoriesController(ICategoryRepository categoryRepository)
{
_categoryRepository = categoryRepository;
}
<span style="color:#008000;">/// <summary></span>
<span style="color:#008000;">/// Get category by Id</span>
<span style="color:#008000;">/// </summary></span>
<span style="color:#008000;">/// <remarks>Returns a single category</remarks></span>
<span style="color:#008000;">/// <param name="categoryId">Id of category to return</param></span>
<span style="color:#008000;">/// <param name="cancellationToken"></param></span>
<span style="color:#008000;">/// <response code="200">successful operation</response></span>
<span style="color:#008000;">/// <response code="401">Not authorized</response></span>
<span style="color:#008000;">/// <response code="404">Category not found</response></span>
[HttpGet]
[Consumes(<span style="color:#a31515;">"application/json"</span>)]
[Route(<span style="color:#a31515;">"{categoryId:Guid}"</span>)]
[SwaggerOperation(<span style="color:#a31515;">"GetCategoryById"</span>)]
[SwaggerResponse(statusCode: 200, type: <span style="color:#0000ff;">typeof</span>(Category), description: <span style="color:#a31515;">"Successful operation"</span>)]
[SwaggerResponse(statusCode: 404, type: <span style="color:#0000ff;">typeof</span>(ApiError), description: <span style="color:#a31515;">"Category not found"</span>)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(GetCategoryResponse), StatusCodes.Status200OK)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status400BadRequest)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status404NotFound)]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">async</span> Task<IActionResult> GetCategoryById([FromRoute] Guid categoryId, CancellationToken cancellationToken)
{
<span style="color:#008000;">//Implementation</span>
}
<span style="color:#008000;">/// <summary></span>
<span style="color:#008000;">/// Get all categories</span>
<span style="color:#008000;">/// </summary></span>
<span style="color:#008000;">/// <param name="cancellationToken"></param></span>
<span style="color:#008000;">/// <remarks>Returns all categories</remarks></span>
<span style="color:#008000;">/// <response code="200">Successful Operation</response></span>
<span style="color:#008000;">/// <response code="401">Not authorized</response></span>
[HttpGet]
[Consumes(<span style="color:#a31515;">"application/json"</span>)]
[Route(<span style="color:#a31515;">"/Categories/GetAllCategories"</span>)]
[SwaggerOperation(<span style="color:#a31515;">"GetAllCategories"</span>)]
[SwaggerResponse(statusCode: 200, type: <span style="color:#0000ff;">typeof</span>(Category), description: <span style="color:#a31515;">"Successful Operation"</span>)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(List<Category>), StatusCodes.Status200OK)]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">async</span> Task<IActionResult> GetAllCategories(CancellationToken cancellationToken)
{
<span style="color:#008000;">//Implementation</span>
}
<span style="color:#008000;">/// <summary></span>
<span style="color:#008000;">/// Add a new category</span>
<span style="color:#008000;">/// </summary></span>
<span style="color:#008000;">/// <remarks>Adds a new category</remarks></span>
<span style="color:#008000;">/// <param name="body">Category object that needs to be added</param></span>
<span style="color:#008000;">/// <param name="cancellationToken"></param></span>
<span style="color:#008000;">/// <response code="201">Category created</response></span>
<span style="color:#008000;">/// <response code="400">Invalid input</response></span>
<span style="color:#008000;">/// <response code="401">Not authorized</response></span>
[HttpPost]
[Consumes(<span style="color:#a31515;">"application/json"</span>)]
[SwaggerOperation(<span style="color:#a31515;">"AddCategory"</span>)]
[SwaggerResponse(statusCode: 201, type: <span style="color:#0000ff;">typeof</span>(CategoryRequest), description: <span style="color:#a31515;">"Category created"</span>)]
[SwaggerResponse(statusCode: 400, type: <span style="color:#0000ff;">typeof</span>(ApiError), description: <span style="color:#a31515;">"Invalid input"</span>)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(Category), StatusCodes.Status201Created)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status400BadRequest)]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">async</span> Task<IActionResult> AddCategory([FromBody] CategoryRequest body, CancellationToken cancellationToken)
{
<span style="color:#008000;">//Implementation</span>
}
<span style="color:#008000;">/// <summary></span>
<span style="color:#008000;">/// Update category</span>
<span style="color:#008000;">/// </summary></span>
<span style="color:#008000;">/// <remarks>Updates category</remarks></span>
<span style="color:#008000;">/// <param name="body">Category object that needs to be updated</param></span>
<span style="color:#008000;">/// <param name="categoryId"></param></span>
<span style="color:#008000;">/// <param name="cancellationToken"></param></span>
<span style="color:#008000;">/// <response code="200">successful operation</response></span>
<span style="color:#008000;">/// <response code="401">Not authorized</response></span>
<span style="color:#008000;">/// <response code="404">Category not found</response></span>
[HttpPut]
[Route(<span style="color:#a31515;">"{categoryId:guid}"</span>)]
[Consumes(<span style="color:#a31515;">"application/json"</span>)]
[SwaggerOperation(<span style="color:#a31515;">"UpdateCategory"</span>)]
[SwaggerResponse(statusCode: 200, type: <span style="color:#0000ff;">typeof</span>(Category), description: <span style="color:#a31515;">"Successful Operation"</span>)]
[SwaggerResponse(statusCode: 404, type: <span style="color:#0000ff;">typeof</span>(ApiError), description: <span style="color:#a31515;">"Category not found"</span>)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(Category), StatusCodes.Status200OK)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status400BadRequest)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status404NotFound)]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">async</span> Task<IActionResult> UpdateCategory([FromBody] CategoryRequest body, [FromRoute] Guid categoryId, CancellationToken cancellationToken)
{
<span style="color:#008000;">//Implementation</span>
}
<span style="color:#008000;">/// <summary></span>
<span style="color:#008000;">/// Deletes a category by Id</span>
<span style="color:#008000;">/// </summary></span>
<span style="color:#008000;">/// <param name="categoryId">Category id to delete</param></span>
<span style="color:#008000;">/// <param name="cancellationToken"></param></span>
<span style="color:#008000;">/// <response code="200">successful operation</response></span>
<span style="color:#008000;">/// <response code="401">Not authorized</response></span>
<span style="color:#008000;">/// <response code="404">Category not found</response></span>
[HttpDelete]
[Consumes(<span style="color:#a31515;">"application/json"</span>)]
[Route(<span style="color:#a31515;">"{categoryId:Guid}"</span>)]
[SwaggerOperation(<span style="color:#a31515;">"DeleteCategory"</span>)]
[SwaggerResponse(statusCode: 200, type: <span style="color:#0000ff;">typeof</span>(Category), description: <span style="color:#a31515;">"Successful Operation"</span>)]
[SwaggerResponse(statusCode: 404, type: <span style="color:#0000ff;">typeof</span>(ApiError), description: <span style="color:#a31515;">"Category not found"</span>)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(<span style="color:#0000ff;">bool</span>), StatusCodes.Status200OK)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status400BadRequest)]
[ProducesResponseType(<span style="color:#0000ff;">typeof</span>(ApiError), StatusCodes.Status404NotFound)]
<span style="color:#0000ff;">public</span> <span style="color:#0000ff;">async</span> Task<IActionResult> DeleteCategory(Guid categoryId, CancellationToken cancellationToken)
{
<span style="color:#008000;">//Implementation</span>
}
}</code></pre>
<p></p>
<p></p>
<h3 style="text-align: left;">References:</h3><div><a href="https://learn.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-7.0&tabs=visual-studio">https://learn.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-7.0&tabs=visual-studio</a></div><br /><br /></div>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-40884383877414958632023-01-25T18:01:00.002-05:002023-01-25T18:04:50.850-05:00Rapidly Setting Up A Development PC with Chocolatey<p>This is an update to my earlier post: <a href="https://sixfootcoder.blogspot.com/2016/04/rapidly-setting-up-azure-pc-with.html">https://sixfootcoder.blogspot.com/2016/04/rapidly-setting-up-azure-pc-with.html</a></p><p>To rapidly setup a development PC.</p><p><br /></p><h2 style="text-align: left;">Install Chocolately</h2><p><a href="https://chocolatey.org/install">https://chocolatey.org/install</a></p><div><br /></div><h2 style="text-align: left;">Create InstallApp.bat</h2><div><div>Create a batch file that will install individual applications called InstallApp.bat</div><div><br /></div><div><span style="font-family: courier;">echo *******************************************************************************</span></div><div><span style="font-family: courier;">echo %1 is installing now !</span></div><div><span style="font-family: courier;">echo *******************************************************************************</span></div><div><span style="font-family: courier;">cinst %1 -y --allow-empty-checksums --ignore-checksum</span></div></div><div><br /></div><div><br /></div><h2 style="text-align: left;">Create DesktopInstall.bat</h2><div>Create a batch file called DesktopInstall.bat that will install individual applications with InstallApp.bat. Add REM before any entry you don't want.</div><div><br /></div><div><div><span style="font-family: courier;">REM Media</span></div><div><span style="font-family: courier;">call InstallApp paint.net</span></div><div><span style="font-family: courier;">call InstallApp picpick.portable</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Web</span></div><div><span style="font-family: courier;">call InstallApp firefox</span></div><div><span style="font-family: courier;">call InstallApp googlechrome</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Video Conferencing and Messaging</span></div><div><span style="font-family: courier;">call InstallApp microsoft-teams.install</span></div><div><span style="font-family: courier;">call InstallApp slack</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Utilities</span></div><div><span style="font-family: courier;">call InstallApp 7zip</span></div><div><span style="font-family: courier;">call InstallApp filezilla</span></div><div><span style="font-family: courier;">call InstallApp chocolateygui</span></div><div><span style="font-family: courier;">call InstallApp winmerge</span></div><div><span style="font-family: courier;">call InstallApp putty.install</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Developer Tools before Visual Studio</span></div><div><span style="font-family: courier;">call InstallApp expresso</span></div><div><span style="font-family: courier;">call InstallApp git.install</span></div><div><span style="font-family: courier;">call InstallApp tortoisegit</span></div><div><span style="font-family: courier;">call InstallApp markdownmonster</span></div><div><span style="font-family: courier;">call InstallApp postman</span></div><div><span style="font-family: courier;">call InstallApp nugetpackageexplorer</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM VS Code</span></div><div><span style="font-family: courier;">call InstallApp vscode.install</span></div><div><span style="font-family: courier;">call InstallApp vscode-prettier</span></div><div><span style="font-family: courier;">call InstallApp vscode-eslint</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Node</span></div><div><span style="font-family: courier;">call InstallApp nodejs.install</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Visual Studio 2019</span></div><div><span style="font-family: courier;">call InstallApp visualstudio2019community</span></div><div><span style="font-family: courier;">call InstallApp visualstudio2019-workload-netweb</span></div><div><span style="font-family: courier;"><br /></span></div><div><span style="font-family: courier;">REM Visual Studio 2022</span></div><div><span style="font-family: courier;">call InstallApp visualstudio2022community</span></div><div><span style="font-family: courier;">call InstallApp visualstudio2022-workload-netweb</span></div><div><br /></div><div><br /></div></div><p><br /></p>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-72669927465575302392022-05-25T07:48:00.005-04:002022-05-25T07:51:21.072-04:00Example ElasticSearch Queries<p>Overview</p><p>There are three different match types in ElasticSearch</p><p></p><ul style="text-align: left;"><li>term - the whole field must match. This has a limit of matching only the first 256 characters.</li><li>wildcard - ability to search for partial words. Example: break* will match break and breaking. This also has a limit of 256 characters.</li><li>match_phrase - This matches on a word boundary and can go longer than 256 characters.</li></ul><div>Case insensitive searches are super slow. Create a lowercase field in ElasticSearch instead.</div><div><br /></div><div>Example queries that can be used for ElasticSearch and Lucene</div><div></div><p></p><div style="background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div># Count items in an index</div><div>GET customer_index/_count</div><div>{</div><div> <span style="color: #9cdcfe;">"query"</span> : {</div><div> <span style="color: #9cdcfe;">"match_all"</span> : {}</div><div> }</div><div>}</div><br /><div># Get top <span style="color: #b5cea8;">200</span> from the customer_index</div><div>GET customer_index/_search</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">200</span>,</div><div> <span style="color: #9cdcfe;">"query"</span> : {</div><div> <span style="color: #9cdcfe;">"match_all"</span> : {}</div><div> }</div><div>}</div><br /><div># Return the top <span style="color: #b5cea8;">200</span> products that are movies</div><div>GET product_index/_search</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">200</span>,</div><div> <span style="color: #9cdcfe;">"query"</span> : {</div><div> <span style="color: #9cdcfe;">"bool"</span> : {</div><div> <span style="color: #9cdcfe;">"must"</span> : [</div><div> {</div><div> <span style="color: #9cdcfe;">"match"</span> : {</div><div> <span style="color: #9cdcfe;">"category"</span> : <span style="color: #ce9178;">"Movie"</span></div><div> }</div><div> } </div><div> ]</div><div> }</div><div> }</div><div>}</div><br /><div># Search for any products that have DVD in the name with a wildcard</div><div>GET product_index/_search</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">200</span>,</div><div> <span style="color: #9cdcfe;">"query"</span> : {</div><div> <span style="color: #9cdcfe;">"wildcard"</span> : {</div><div> <span style="color: #9cdcfe;">"name"</span> : {</div><div> <span style="color: #9cdcfe;">"value"</span> : <span style="color: #ce9178;">"*DVD*"</span></div><div> }</div><div> }</div><div> }</div><div>}</div><br /><div># Get an aggregate list of product categories sorted alphabetically</div><div>GET product_index/_search</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">0</span>,</div><div> <span style="color: #9cdcfe;">"aggs"</span> : {</div><div> <span style="color: #9cdcfe;">"category"</span> : {</div><div> <span style="color: #9cdcfe;">"terms"</span> : {</div><div> <span style="color: #9cdcfe;">"field"</span> : <span style="color: #ce9178;">"category.keyword"</span>,</div><div> <span style="color: #9cdcfe;">"order"</span> : {</div><div> <span style="color: #9cdcfe;">"_key"</span> : <span style="color: #ce9178;">"asc"</span></div><div> }</div><div> }</div><div> }</div><div> }</div><div>}</div><br /><div># Get a list of physical products that do not have a category</div><div>GET product_index/_search</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">200</span>,</div><div> <span style="color: #9cdcfe;">"query"</span> : {</div><div> <span style="color: #9cdcfe;">"bool"</span> : {</div><div> <span style="color: #9cdcfe;">"must_not"</span> : [</div><div> {</div><div> <span style="color: #9cdcfe;">"exists"</span> : {</div><div> <span style="color: #9cdcfe;">"field"</span> : <span style="color: #ce9178;">"category"</span></div><div> }</div><div> }</div><div> ],</div><div> <span style="color: #9cdcfe;">"minimum_should_match"</span> : <span style="color: #b5cea8;">1</span>,</div><div> <span style="color: #9cdcfe;">"should"</span> : [</div><div> {</div><div> <span style="color: #9cdcfe;">"match"</span> : {</div><div> <span style="color: #9cdcfe;">"product_type"</span> : {</div><div> <span style="color: #9cdcfe;">"query"</span> : <span style="color: #ce9178;">"Physical"</span></div><div> }</div><div> }</div><div> }</div><div> ]</div><div> }</div><div> }</div><div>}</div><br /><br /><div># Group by Aggregate</div><div>GET _search/</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">0</span>, </div><div> <span style="color: #9cdcfe;">"query"</span> : {</div><div> <span style="color: #9cdcfe;">"bool"</span> : {</div><div> <span style="color: #9cdcfe;">"must"</span> : [</div><div> {</div><div> <span style="color: #9cdcfe;">"match"</span> : {</div><div> <span style="color: #9cdcfe;">"product_type"</span> : <span style="color: #ce9178;">"Physical"</span></div><div> }</div><div> },</div><div> {</div><div> <span style="color: #9cdcfe;">"wildcard"</span> : {</div><div> <span style="color: #9cdcfe;">"category.keyword"</span> : {</div><div> <span style="color: #9cdcfe;">"value"</span> : <span style="color: #ce9178;">"*DVD*"</span></div><div> }</div><div> }</div><div> }</div><div> </div><div> ]</div><div> }</div><div> },</div><div> <span style="color: #9cdcfe;">"aggs"</span> : {</div><div> <span style="color: #9cdcfe;">"group_by_column"</span> : {</div><div> <span style="color: #9cdcfe;">"terms"</span> : {</div><div> <span style="color: #9cdcfe;">"field"</span> : <span style="color: #ce9178;">"category.keyword"</span>,</div><div> <span style="color: #9cdcfe;">"size"</span> : <span style="color: #b5cea8;">10000</span></div><div> }</div><div> }</div><div> </div><div> }</div><div>}</div><br /><div><br /></div><div># Perform a search and order by using functions</div><div>GET product_index/_search</div><div>{</div><div> <span style="color: #9cdcfe;">"size"</span>: <span style="color: #b5cea8;">200</span>,</div><div> <span style="color: #9cdcfe;">"query"</span>: {</div><div> <span style="color: #9cdcfe;">"function_score"</span>: {</div><div> <span style="color: #9cdcfe;">"query"</span>: {</div><div> <span style="color: #9cdcfe;">"bool"</span>: {</div><div> <span style="color: #9cdcfe;">"must"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"bool"</span>: {</div><div> <span style="color: #9cdcfe;">"minimum_should_match"</span>: <span style="color: #b5cea8;">1</span>,</div><div> <span style="color: #9cdcfe;">"should"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"term"</span>: {</div><div> <span style="color: #9cdcfe;">"category.keyword"</span>: <span style="color: #ce9178;">"Books"</span></div><div> }</div><div> },</div><div> {</div><div> <span style="color: #9cdcfe;">"term"</span>: {</div><div> <span style="color: #9cdcfe;">"category.keyword"</span>: <span style="color: #ce9178;">"Movies"</span></div><div> }</div><div> }</div><div> ]</div><div> }</div><div> }</div><div> ],</div><div> <span style="color: #9cdcfe;">"minimum_should_match"</span>: <span style="color: #b5cea8;">1</span>,</div><div> <span style="color: #9cdcfe;">"should"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"match_phrase"</span>: {</div><div> <span style="color: #9cdcfe;">"nameLowercase"</span>: <span style="color: #ce9178;">"journey"</span></div><div> }</div><div> },</div><div> {</div><div> <span style="color: #9cdcfe;">"match_phrase"</span>: {</div><div> <span style="color: #9cdcfe;">"descriptionLowercase"</span>: <span style="color: #ce9178;">"journey"</span></div><div> }</div><div> }</div><div> ]</div><div> }</div><div> },</div><div> <span style="color: #9cdcfe;">"functions"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"filter"</span>: {</div><div> <span style="color: #9cdcfe;">"bool"</span>: {</div><div> <span style="color: #9cdcfe;">"must"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"term"</span>: {</div><div> <span style="color: #9cdcfe;">"nameLowercase.keyword"</span>: <span style="color: #ce9178;">"journey"</span></div><div> }</div><div> }</div><div> ]</div><div> }</div><div> },</div><div> <span style="color: #9cdcfe;">"weight"</span>: <span style="color: #b5cea8;">3</span></div><div> },</div><div> {</div><div> <span style="color: #9cdcfe;">"filter"</span>: {</div><div> <span style="color: #9cdcfe;">"bool"</span>: {</div><div> <span style="color: #9cdcfe;">"must"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"match_phrase"</span>: {</div><div> <span style="color: #9cdcfe;">"nameLowercase"</span>: <span style="color: #ce9178;">"journey"</span></div><div> }</div><div> }</div><div> ]</div><div> }</div><div> },</div><div> <span style="color: #9cdcfe;">"weight"</span>: <span style="color: #b5cea8;">2</span></div><div> },</div><div> {</div><div> <span style="color: #9cdcfe;">"filter"</span>: {</div><div> <span style="color: #9cdcfe;">"bool"</span>: {</div><div> <span style="color: #9cdcfe;">"must"</span>: [</div><div> {</div><div> <span style="color: #9cdcfe;">"match_phrase"</span>: {</div><div> <span style="color: #9cdcfe;">"descriptionLowercase"</span>: <span style="color: #ce9178;">"journey"</span></div><div> }</div><div> }</div><div> ]</div><div> }</div><div> },</div><div> <span style="color: #9cdcfe;">"weight"</span>: <span style="color: #b5cea8;">1</span></div><div> }</div><div> ],</div><div> <span style="color: #9cdcfe;">"score_mode"</span>: <span style="color: #ce9178;">"first"</span>,</div><div> <span style="color: #9cdcfe;">"boost_mode"</span>: <span style="color: #ce9178;">"replace"</span></div><div> }</div><div> },</div><div> <span style="color: #9cdcfe;">"sort"</span>: {</div><div> <span style="color: #9cdcfe;">"_score"</span>: {</div><div> <span style="color: #9cdcfe;">"order"</span>: <span style="color: #ce9178;">"desc"</span></div><div> }</div><div> }</div><div>}</div><br /></div><p><br /></p><p><br /></p>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-34575247494208927952020-04-24T11:48:00.001-04:002020-04-24T12:05:10.168-04:00Becoming an Automated Tester Using TypeScript, Selenium, NodeJS, and Mocha<h2>
Overview</h2>
In order to be an automated tester you must be able to:<br />
<br />
<ul>
<li>Develop in JavaScript</li>
<li>Develop in the TypeScript language which is a super set of the JavaScript language.</li>
<li>Understand NodeJs which is a JavaScript runtime</li>
<li>Use yarn which downloads packages that other people have built in TypeScript or JavaScript.</li>
<li>Work with Selenium which is a library that interacts with the Web Browser.</li>
<li>Work with Mocha which is a testing framework.</li>
<li>Use regular expressions for matching text on a web page.</li>
</ul>
<h2>
<br /></h2>
<h2>
The path to being an automated tester</h2>
<br />
<b>Learn JavaScript</b><br />
<br />
<ul>
<li>JavaScript Tutorial for Beginners: Learn JavaScript in 1 Hour</li>
<ul>
<li><a href="https://www.youtube.com/watch?v=W6NZfCO5SIk">https://www.youtube.com/watch?v=W6NZfCO5SIk</a></li>
</ul>
</ul>
<br />
<br />
<ul>
<li>JavaScript Courses</li>
<ul>
<li><a href="http://sixfootcoder.blogspot.com/2017/02/javascript-resources.html">http://sixfootcoder.blogspot.com/2017/02/javascript-resources.html</a></li>
</ul>
</ul>
<br />
<br />
<b>Learn TypeScript</b><br />
<br />
<ul>
<li>Take all these courses except the one on Angular</li>
<ul>
<li><a href="http://sixfootcoder.blogspot.com/2017/02/typescript-resources.html">http://sixfootcoder.blogspot.com/2017/02/typescript-resources.html</a></li>
</ul>
</ul>
<br />
<b>Learn NodeJS</b><br />
<br />
<ul>
<li>Node.js Tutorial for Beginners: Learn Node in 1 Hour</li>
<ul>
<li><a href="https://www.youtube.com/watch?v=TlB_eWDSMt4">https://www.youtube.com/watch?v=TlB_eWDSMt4</a></li>
</ul>
</ul>
<br />
<br />
<b>Learn Yarn</b><br />
<br />
<ul>
<li><a href="http://sixfootcoder.blogspot.com/2017/04/yarn-package-manager.html">http://sixfootcoder.blogspot.com/2017/04/yarn-package-manager.html</a></li>
</ul>
<br />
<br />
<b>Learn Selenium </b><br />
<br />
<ul>
<li><a href="https://www.youtube.com/watch?v=X3pTXG9a1oQ&list=PLt1BzgDPWET4m4c4hrOZe--apdA6P2WoA">https://www.youtube.com/watch?v=X3pTXG9a1oQ&list=PLt1BzgDPWET4m4c4hrOZe--apdA6P2WoA</a></li>
</ul>
<br />
<b>Learn Mocha</b><br />
<br />
<ul>
<li>https://testautomationu.applitools.com/mocha-javascript-tests/</li>
</ul>
<br />
<br />
<b>Learn Regular Expressions</b><br />
<br />
<ul>
<li><a href="https://www.youtube.com/watch?v=r6I-Ahc0HB4&list=PL4cUxeGkcC9g6m_6Sld9Q4jzqdqHd2HiD">https://www.youtube.com/watch?v=r6I-Ahc0HB4&list=PL4cUxeGkcC9g6m_6Sld9Q4jzqdqHd2HiD</a></li>
</ul>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-73168474234910105022019-09-06T13:44:00.000-04:002019-09-06T13:44:20.708-04:00Microsoft.Build.Utilites 2.0.0 was not able to reference the assembly Telerik.Sitefinity.OpenAccessWhen running an older version of Sitefinity under Windows 10, the Telerik enhancer.exe requires the .NET Framework 3.5 to be installed. By default Windows 10 does not come with the .NET Framework 3.5 so you will need to install it. Windows 10 comes with the .NET Framework 4.6 installed by default.<br />
<br />
Here is the error for future reference:<br />
Microsoft.Build.Utilites 2.0.0 was not able to reference the assembly Telerik.Sitefinity.OpenAccess in \packages\Telerik.DataAccess.Fluent.2015.3.926.1\tools\enhancer\enhancer.exeGreg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-41807006646256032432019-08-16T14:58:00.001-04:002019-08-16T14:58:06.225-04:00Deleting Logs in SalesforceSometimes Salesforce logs are clog up the environment and you need to delete them. <br />
<br />
Logs are found in two different places in Salesforce.<br />
<br />
<h3>
Deleting Apex Logs</h3>
<div>
If you receive this message, this is an indicator that you need to delete your Apex Logs</div>
<div>
<br /></div>
<div>
<span style="color: red;">The Developer Console didn't set the DEVELOPER_LOG trace flag on your user. Having an active trace flag triggers debug logging. You have 251 MB of the maximum 250 MB of debug logs. Before you can edit trace flags, delete some debug logs.</span></div>
<br />
1. Click the gear icon and choose developer console<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1RiZ8GSoBM3xjbXhgTC5rNvmtCs0T6YljAcGTsVBc2dUNr_GhyA7Q-2TKB4ZEQuSfj351sx2K2tl08QrQvi82vbz6jIxfRzg7NIPfCodCJucl6B8vQ1boIzSZ1Awn2-1vRY-LVhovBHr5/s1600/DeveloperConsole.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="209" data-original-width="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1RiZ8GSoBM3xjbXhgTC5rNvmtCs0T6YljAcGTsVBc2dUNr_GhyA7Q-2TKB4ZEQuSfj351sx2K2tl08QrQvi82vbz6jIxfRzg7NIPfCodCJucl6B8vQ1boIzSZ1Awn2-1vRY-LVhovBHr5/s1600/DeveloperConsole.png" /></a></div>
<br />
2. In the query editor tab enter the query and click Execute<br />
<br />
SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu8vs48KNP2iatNQmgkChSPibDNza5yLrQ_ydlwwIHV-3w1NIoWZG7-YQqmsF-i-YbRvJYiJlNJFk4cAfgFkD_CXZwY7tmMkOOZVXGaenMeVXWN2rpE7wsVKKjhDiThWaAqDFDlWKV5nrb/s1600/QueryEditor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="203" data-original-width="528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu8vs48KNP2iatNQmgkChSPibDNza5yLrQ_ydlwwIHV-3w1NIoWZG7-YQqmsF-i-YbRvJYiJlNJFk4cAfgFkD_CXZwY7tmMkOOZVXGaenMeVXWN2rpE7wsVKKjhDiThWaAqDFDlWKV5nrb/s1600/QueryEditor.png" /></a></div>
<br />
3. Select the rows to delete and click Delete Row<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjjay4znH82nzmcuK1V4uM1nuGz4CNcZqeYPNahCNb7vJ2a_k4Z8oXhThnB5Rqoh4HJqJAXtsDfwk1ieANK2FPTzwhm5i-oG6dG8sdhl2n01ogaxEr4wQjcgWVO_11NyCA-2mcOpIn24KP/s1600/DeleteRow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="52" data-original-width="364" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjjay4znH82nzmcuK1V4uM1nuGz4CNcZqeYPNahCNb7vJ2a_k4Z8oXhThnB5Rqoh4HJqJAXtsDfwk1ieANK2FPTzwhm5i-oG6dG8sdhl2n01ogaxEr4wQjcgWVO_11NyCA-2mcOpIn24KP/s1600/DeleteRow.png" /></a></div>
<br />
<br />
<h3>
Remove from Debug Logs</h3>
<br />
1. Click on Gear Icon and then Setup<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik_yqS8TJG9UU3Xk-KYcTA0KdsWNSib__3hUrNTHB_BjZyis43ldSa4LRCLpe1HD0zvWlsAvRNf7AFO8W3kitah9MYVUTYGuHxj4qNCanJMbgicM7axX85gnxvMIES-b7kUarISSZhHEqI/s1600/Setup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="210" data-original-width="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik_yqS8TJG9UU3Xk-KYcTA0KdsWNSib__3hUrNTHB_BjZyis43ldSa4LRCLpe1HD0zvWlsAvRNf7AFO8W3kitah9MYVUTYGuHxj4qNCanJMbgicM7axX85gnxvMIES-b7kUarISSZhHEqI/s1600/Setup.png" /></a></div>
<br />
<br />
2. Search for Logs<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ9HW2mBE502rE28xPScHlzLbZ0XsErj2GpOUCj9chuEe2Gya1h6Lv16b3JNcaAdyW4ZL_zuYwy1ZSEzUM5py3egr75MQI8WXuGqd-cVsUrMHYZ7yZtnbPGwu91Ge6zZcFM7wdJs68ScQk/s1600/DebugLogs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="406" data-original-width="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ9HW2mBE502rE28xPScHlzLbZ0XsErj2GpOUCj9chuEe2Gya1h6Lv16b3JNcaAdyW4ZL_zuYwy1ZSEzUM5py3egr75MQI8WXuGqd-cVsUrMHYZ7yZtnbPGwu91Ge6zZcFM7wdJs68ScQk/s1600/DebugLogs.png" /></a></div>
<br />
<br />
3. Delete all the Logs or Just for your user<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMa3kftsoRIZAv72LCTfTqdWlmeN_wtNAKSyeLXizUbWymwuZzawNLI5RJw2XCCXFUNgor2KLHImix2uN5JUvzOYOyNWjm4ZGYDS3wmb4a8Bnug0TnNt_-4GxkZ15XGetOJz_gzOHvibrV/s1600/DeleteLogs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="102" data-original-width="557" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMa3kftsoRIZAv72LCTfTqdWlmeN_wtNAKSyeLXizUbWymwuZzawNLI5RJw2XCCXFUNgor2KLHImix2uN5JUvzOYOyNWjm4ZGYDS3wmb4a8Bnug0TnNt_-4GxkZ15XGetOJz_gzOHvibrV/s1600/DeleteLogs.png" /></a></div>
<br />
<br />
<h3>
<br /></h3>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-30272788179203495682019-07-02T15:18:00.000-04:002019-07-03T09:15:40.347-04:00Creating an IIS Redirect Rule from Subdomain to the Root DomainIIS Rewrite Rules have a lot of inherent complexity. They use regular expressions and are difficult to debug. The server variables have little documentation provided by Microsoft. Recently we had an ask from the business to redirect any requests for subdomains to the main domain. While this is simple to understand it is difficult to write.<br />
<br />
Before you create and debug a rewrite rule you need a couple things:<br />
1. Install IIS by going into Programs and Features then Windows Features<br />
2. Install the Web Platform Installer <a href="https://www.microsoft.com/web/downloads/platform.aspx">https://www.microsoft.com/web/downloads/platform.aspx</a> This installs modules for IIS like NuGet installs packages for .NET<br />
3. Use the Web Platform Installer to install the Rewrite Module<br />
<br />
Here is the end result:<br />
<br />
<script src="https://gist.github.com/GregFinzer/cc930fd133cd7c7ebcc5fe6e9c1a2ac0.js"></script>
<br />
<b><br /></b>
<b>Match URL</b><br />
The thing that hung me up for most of the time was the match url. This is not the full URL as you would expect but simply the page that was requested like default.aspx. This is Mistake #1 from Lex Li: <a href="https://blog.lextudio.com/the-very-common-mistakes-when-using-iis-url-rewrite-module-a2ab7e4fee59">https://blog.lextudio.com/the-very-common-mistakes-when-using-iis-url-rewrite-module-a2ab7e4fee59</a><br />
<br />
<b>Condition Order</b><br />
In order to do back references to conditions (see the {C:2} and {C:3} variables) you have to put the negate false conditions first. If you don't the back reference does not work.<br />
<br />
<b>HTTP_HOST Matching</b><br />
If you do not put the regular expression carat ^ for start and the dollar $ sign for end, IIS will redirect until the URL is too long and it throws an error.<br />
<br />
<b>Putting It All Together</b><br />
https://www. - We always want to redirect to secure www<br />
{C:2} and {C:3} - This is a back reference to the last condition, the last set of parenthesis.<br />
{R:1} - This is the requested page from the Match URL<br />
<br />
<h2>
Debugging the Redirect Rule</h2>
<div>
1. Here is some excellent documentation how to create a simple test file to debug your rewrite rule:</div>
<div>
<a href="https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/creating-rewrite-rules-for-the-url-rewrite-module">https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/creating-rewrite-rules-for-the-url-rewrite-module</a></div>
<div>
<br /></div>
<div>
2. I used Expresso to debug the regular expression to match the subdomain.rootdomain. You can also use IIS by double clicking on the Re-write module for the site. <a href="http://www.ultrapico.com/expresso.htm">http://www.ultrapico.com/expresso.htm</a> </div>
<div>
<br /></div>
<div>
3. What I found to be very useful was to change the redirect url to a query string to see what the variables were. </div>
<action type="Redirect" url="http://www.somesitethatdoesnotexist.com/?{C:2}-{R:1}" appendQueryString="false" /><br />
<br />
<br />
Here is the reference documentation from Microsoft:<br />
<a href="https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/url-rewrite-module-20-configuration-reference">https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/url-rewrite-module-20-configuration-reference</a><br />
<br />
<br />
<br />
<br />
<br />Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-47619366644890455652019-06-21T09:59:00.003-04:002019-09-06T13:45:15.196-04:00Resetting the Admin Password in SitefinityIf you lost the admin password for a site you can reset the password for the admin user in the database. This will set the password format to clear text with no salt for the encryption.<br />
<br />
<span style="font-family: "courier new"; font-size: x-small;">
<span style="color: blue;">UPDATE</span> <span style="color: maroon;">sf_users</span>
<br /><span style="color: blue;">SET</span> <span style="color: maroon;">passwd</span> <span style="color: silver;">=</span> <span style="color: red;">'password'</span><span style="color: silver;">,</span>
<br /> <span style="color: maroon;">salt</span> <span style="color: silver;">=</span> <span style="color: blue;">NULL</span><span style="color: silver;">,</span>
<br /> <span style="color: maroon;">password_format</span> <span style="color: silver;">=</span> <span style="color: black;">0</span>
<br /><span style="color: blue;">WHERE</span> <span style="color: maroon;">user_name</span> <span style="color: silver;">=</span> <span style="color: red;">'someadminuser'</span>
</span>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-22963056681722208872019-05-21T13:02:00.001-04:002019-05-21T13:02:20.167-04:00How to redirect from HTTP to HTTPS in a web.config in CrownPeak CMS<br />
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<rewrite><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<rules><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<%<u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
if (context.PublishingPackage.<wbr></wbr>PackageName.Contains("Live")<u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
{<u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
%><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<rule name="Redirect to https" stopProcessing="true"><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<match url="(.*)" /><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<conditions><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<add input="{HTTPS}" pattern="off" ignoreCase="true" /><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
</conditions><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<action type="Redirect" url="https://{HTTP_HOST}{<wbr></wbr>REQUEST_URI}" redirectType="Permanent" appendQueryString="false" /><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
</rule><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<%<u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
}<u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
%><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
</rules><u></u><u></u></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
</rewrite></div>
<div class="MsoNormal" style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: small;">
<br /></div>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-13292644718570244702019-02-11T12:36:00.000-05:002019-02-11T12:36:32.439-05:00What happened to my Salesforce System.Debug statements?<br />
<div class="MsoNormal">
On our project we have complex report generation which
creates a debug log file at the 5MB limit when the Apex Debug Log Level is set
to finest.<span style="mso-spacerun: yes;"> </span>According to Salesforce: <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
“Each debug log must be 5 MB or smaller. Debug logs that are
larger than 5 MB are reduced in size by removing older log lines, such as log
lines for earlier System.debug statements. The log lines can be removed from
any location, not just the start of the debug log.“<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span class="MsoHyperlink"><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_debugging_debug_log.htm">https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_debugging_debug_log.htm</a></span><o:p></o:p></div>
<div class="MsoNormal">
<br />
If you just want to see the debug statements, simply log at the error level and
then set everything else to none.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "courier new" , "courier" , monospace;">System.debug(LoggingLevel.ERROR, ‘some logging message’);</span><o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Debug Levels<o:p></o:p></div>
<ul>
<li>Database : None</li>
<li>Workflow : None</li>
<li>Validation : None</li>
<li>Callouts : None</li>
<li>Apex Code : Error</li>
<li>Apex Profiling : None</li>
<li>Visualforce : None</li>
<li>System: None</li>
<li>Wave: None</li>
<li>Nba: None</li>
</ul>
<div>
<br /></div>
<div>
<div class="MsoNormal">
If you want to debug in Visual Studio at the Apex finest
level, break your code up into small testable pieces so that you can pinpoint
errors and the log files can be under the 5MB limit.<span style="mso-spacerun: yes;"> </span>The <span class="MsoHyperlink"><a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">Single
Responsibility</a></span> should be your best friend when working in
Salesforce.<o:p></o:p></div>
</div>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-40122932933855191242019-02-11T12:32:00.001-05:002019-02-11T12:32:24.232-05:00Augmenting Salesforce CLI Commands for VS Code<br />
<div class="MsoNormal">
I have been working with the Salesforce Extension Pack for VS Code and I have been mostly pleased with the capabilities. On my current project, I find myself constantly switching between orgs. I was tired of typing in the command to list out the current org and the command to switch the current org. </div>
<div class="MsoNormal">
There is a great hotkey VS Code extension called terminal-command-keys that allows you to create a hotkey that executes a terminal command. The Salesforce CLI with hotkeys; what could be better!</div>
<div class="MsoNormal">
Here are the steps to use</div>
<div class="MsoNormal">
</div>
<ol>
<li>Install the VS Code extension terminal-command-keys</li>
<li>Edit your keybindings.json by pressing Ctrl-Shift-P on the PC or Command-Shift-P on the Mac. Edit the file on the right</li>
</ol>
<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<!--[if !supportLists]--><o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Add a command to list all your orgs by pressing Ctrl-Shift-l<o:p></o:p></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"key"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"> : </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"ctrl+shift+l"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"command"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"terminalCommandKeys.run"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"args"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"> : <o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"cmd"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"sfdx
force:org:list"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"saveAllFiles"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #569cd6; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">false</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>}<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>},<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Add a command to upload the current file by pressing
Ctrl-Shift-u<o:p></o:p></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"key"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"ctrl+shift+u"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"command"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"terminalCommandKeys.run"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"args"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: {<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"cmd"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"sfdx
force:source:deploy --sourcepath<span style="mso-spacerun: yes;"> </span>${file}
--loglevel fatal"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"newTerminal"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #569cd6; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">false</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"saveAllFiles"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #569cd6; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">true</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"showTerminal"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #569cd6; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">true</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>}<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>},<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Add a command to switch to your development org.<span style="mso-spacerun: yes;"> </span>In my case, the alias is BossSand. Replace
with the alias for your org.<o:p></o:p></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"key"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"> : </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"ctrl+shift+d"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"command"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"terminalCommandKeys.run"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"args"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"> : <o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"cmd"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"sfdx
force:config:set defaultusername=BossSand"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">, <o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"saveAllFiles"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #569cd6; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">false</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>}<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>},<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Add a command to switch to your test org.<span style="mso-spacerun: yes;"> </span>In my case the alias is BossStage. Replace
with the alias for your org.<o:p></o:p></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"key"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"> : </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"ctrl+shift+v"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"command"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"terminalCommandKeys.run"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">,<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"args"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"> : <o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>{<o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"cmd"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #ce9178; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"sfdx
force:config:set defaultusername=BossStage"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">, <o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span></span><span style="color: #9cdcfe; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">"saveAllFiles"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">: </span><span style="color: #569cd6; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">false</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>}<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></div>
<div class="MsoNormal" style="background: #1E1E1E; line-height: 14.25pt; margin-bottom: .0001pt; margin-bottom: 0in;">
<span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";"><span style="mso-spacerun: yes;"> </span>}<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<br />Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-36943900180895719032019-01-18T14:33:00.000-05:002019-01-18T14:37:03.877-05:00Debugging Salesforce Tests with VS CodeDebugging in Salesforce is relatively new and it immature compared to debugging in Visual Studio or Eclipse. Even Microsoft Access has a better debugger than Salesforce. Essentially logs files are created when running tests and then the log files are used to step through the code. It is after the fact debugging, you cannot change the path that the code has gone.<br />
<br />
If you haven't already, set up <a href="https://sixfootcoder.blogspot.com/2019/01/setting-up-vs-code-with-salesforce.html" target="_blank">VS Code for Salesforce</a><br />
<br />
<br />
<ol>
<li>Click the Debug icon</li>
<li>In the drop down list at the top under Debug, Add Configuration. Select Apex Replay Debugger</li>
<li>Make sure that you have pulled all your code and tests down from source control or from your org.</li>
<li>Using Ctrl-Shift-P on Windows or Command-Shift-P on a Mac, select SFDX: Turn On Apex Debug Log for Replay Debugger</li>
<li>Set a break point in your test</li>
<li>Run your test by clicking Run Test above the test method name in VS Code </li>
<li>Using Ctrl-Shift-P on Windows or Command-Shift-P on a Mac, select SFDX: Turn Off Apex Debug Log for Replay Debugger</li>
<li>Using Ctrl-Shift-P on Windows or Command-Shift-P on a Mac, select SFDX: Get Apex Debug Logs</li>
<li>Click the Debug icon</li>
<li>Click the Launch Apex Replay Debugger</li>
<li>You can see local variables on the left and you can step into code</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOCjsYOHbQPgc2h4PM_0Ot4biwx_yJUg_x_0qNd194R1geydjQ_vCZwzwtan2fQtCi-kMBRziSUyhdCq8mHVEzobIET4dbAzLLEPha6O7z4uQEQOgBdReBnAc55DxuKlgjY32tecDHYGLY/s1600/Testing+with+Salesforce.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="867" data-original-width="1600" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOCjsYOHbQPgc2h4PM_0Ot4biwx_yJUg_x_0qNd194R1geydjQ_vCZwzwtan2fQtCi-kMBRziSUyhdCq8mHVEzobIET4dbAzLLEPha6O7z4uQEQOgBdReBnAc55DxuKlgjY32tecDHYGLY/s320/Testing+with+Salesforce.png" width="320" /></a></div>
<div>
<br /></div>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-67823624451515428382019-01-18T13:46:00.001-05:002019-03-08T14:24:08.920-05:00Setting Up VS Code with SalesforceThese are step by step instructions to get VS Code working with Salesforce.<br />
<br />
<br />
<ol>
<li>Go to your Sandbox, under Setup search for Dev Hub. Enable Dev Hub and GA. This will allow you to create scratch orgs.</li>
<li>Install the Salesforce CLI which will allow you to push and pull code and run tests: <a href="https://developer.salesforce.com/tools/sfdxcli">https://developer.salesforce.com/tools/sfdxcli</a></li>
<li>Install VS Code which is now the standard for editing code for Salesforce: <a href="https://code.visualstudio.com/download">https://code.visualstudio.com/download</a></li>
<li>Install Java if you do not have it installed yet. The Salesforce Extension Pack requires it. <a href="https://www.java.com/en/download/">https://www.java.com/en/download/</a></li>
<li>Install the Salesforce Extension Pack. In VS Code, click the extensions icon and search for Salesforce Extension Pack.</li>
<li>Install Lightning Web Components extension in VS Code</li>
</ol>
<div>
If your Salesforce code is in your org and not in source control then you are in Classic Development and not Salesforce DX. </div>
<div>
<br /></div>
<h2>
Classic Development Mode (directly interact with an Org)</h2>
<div>
See these instructions: <br />
<a href="https://forcedotcom.github.io/salesforcedx-vscode/articles/user-guide/org-development-model">https://forcedotcom.github.io/salesforcedx-vscode/articles/user-guide/org-development-model</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<span style="color: red;">* After creating the project, create these folders under the default folder before doing a Retrieve Source From Org: </span><br />
<br />
<ul>
<li><span style="color: red;">classes</span></li>
<li><span style="color: red;">objects</span></li>
</ul>
</div>
<div>
<span style="color: red;"><br /></span></div>
<h2>
Salesforce DX Mode (your source is in GitHub or Bitbucket)</h2>
<div>
Example of cloning a repository, creating a scratch org and pushing the code</div>
<div>
<br /></div>
<div>
<div>
git clone https://github.com/dreamhouseapp/dreamhouse-sfdx</div>
<div>
cd dreamhouse-sfdx</div>
<div>
sfdx force:config:set defaultdevhubusername=your@username.com</div>
<div>
sfdx force:org:create -a dreamhouse -s -f config\project-scratch-def.json -d 7</div>
<div>
sfdx force:source:push</div>
<div>
sfdx force:user:permset:assign -n dreamhouse</div>
<div>
sfdx force:org:open -p /lightning/page/home</div>
</div>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-15509560850804354242018-09-05T12:07:00.001-04:002018-09-05T12:07:43.095-04:00Using Caching in the .NET FrameworkCaching is easy to use in the .NET Framework<div>
<br /></div>
<div>
According to Microsoft:</div>
<div>
"In the .NET Framework 3.5 and earlier versions, ASP.NET provided an in-memory cache implementation in the System.Web.Caching namespace. In previous versions of the .NET Framework, caching was available only in the System.Web namespace and therefore required a dependency on ASP.NET classes. In the .NET Framework 4, the System.Runtime.Caching namespace contains APIs that are designed for both Web and non-Web applications."</div>
<div>
<br /></div>
<div>
Here are a couple methods to Load and Save from the Memory Cache. If the value is not found, it will be null. </div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">public static class Cache</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">{</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> public static TResult Load<TResult>(string cacheKeyName)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ObjectCache cacheInstance = MemoryCache.Default;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> return (TResult)cacheInstance[cacheKeyName];</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> public static T Save<T> (string cacheKeyName, DateTimeOffset expirationDate, T value)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> cacheItemPolicy.AbsoluteExpiration = expirationDate;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ObjectCache cacheInstance = MemoryCache.Default;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> cacheInstance.Set(cacheKeyName, value, cacheItemPolicy);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> return value;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<h3>
<span style="font-family: inherit;">Example Call to Load and Save</span></h3>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">Here is an example of using the load and save with a stopwatch so that the time saved can be shown:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<div style="font-family: "Courier New", Courier, monospace;">
[Test]</div>
<div style="font-family: "Courier New", Courier, monospace;">
public void SimpleLoadAndSaveTest()</div>
<div style="font-family: "Courier New", Courier, monospace;">
{</div>
<div style="font-family: "Courier New", Courier, monospace;">
Stopwatch watch = Stopwatch.StartNew();</div>
<div style="font-family: "Courier New", Courier, monospace;">
string json = Cache.Load<string>("JsonValue");</div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<div style="font-family: "Courier New", Courier, monospace;">
if (json == null)</div>
<div style="font-family: "Courier New", Courier, monospace;">
{</div>
<div style="font-family: "Courier New", Courier, monospace;">
json = GetJsonFromWebService("cf4174ce-96d2-495c-b58a-427d35f64a20");</div>
<div style="font-family: "Courier New", Courier, monospace;">
Cache.Save("JsonValue", DateTimeOffset.Now.AddMinutes(20), json);</div>
<div style="font-family: "Courier New", Courier, monospace;">
}</div>
<div style="font-family: "Courier New", Courier, monospace;">
watch.Stop();</div>
<div style="font-family: "Courier New", Courier, monospace;">
Console.WriteLine(watch.ElapsedMilliseconds);</div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<div style="font-family: "Courier New", Courier, monospace;">
watch.Restart();</div>
<div style="font-family: "Courier New", Courier, monospace;">
json = Cache.Load<string>("JsonValue");</div>
<div style="font-family: "Courier New", Courier, monospace;">
watch.Stop();</div>
<div style="font-family: "Courier New", Courier, monospace;">
Console.WriteLine(watch.ElapsedMilliseconds);</div>
<div style="font-family: "Courier New", Courier, monospace;">
}</div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<div style="font-family: "Courier New", Courier, monospace;">
public string GetJsonFromWebService(string value)</div>
<div style="font-family: "Courier New", Courier, monospace;">
{</div>
<div style="font-family: "Courier New", Courier, monospace;">
Thread.Sleep(1000);</div>
<div style="font-family: "Courier New", Courier, monospace;">
return "{ \"Value\" : \"" + value + "\" }";</div>
<div style="font-family: "Courier New", Courier, monospace;">
}</div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<h3>
<span style="font-family: inherit;">Cache Class</span></h3>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<div>
<span style="font-family: inherit;">I have created a larger caching class where methods can be passed into shorten the code:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<div style="font-family: "Courier New", Courier, monospace;">
<div>
public static class Cache</div>
<div>
{</div>
<div>
public static TResult Load<TResult>(string cacheKeyName)</div>
<div>
{</div>
<div>
ObjectCache cacheInstance = MemoryCache.Default;</div>
<div>
return (TResult)cacheInstance[cacheKeyName];</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static T Save<T> (string cacheKeyName, DateTimeOffset expirationDate, T value)</div>
<div>
{</div>
<div>
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();</div>
<div>
cacheItemPolicy.AbsoluteExpiration = expirationDate;</div>
<div>
ObjectCache cacheInstance = MemoryCache.Default;</div>
<div>
cacheInstance.Set(cacheKeyName, value, cacheItemPolicy);</div>
<div>
return value;</div>
<div>
}</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, int expirationMinutes, Func<TResult> serviceFunction)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, DateTimeOffset.Now.AddMinutes(expirationMinutes), serviceFunction);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, int expirationMinutes, Func<string, TResult> serviceFunction, string stringArg)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, DateTimeOffset.Now.AddMinutes(expirationMinutes), serviceFunction, stringArg);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, int expirationMinutes, Func<long, TResult> serviceFunction, long longArg)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, DateTimeOffset.Now.AddMinutes(expirationMinutes), serviceFunction, longArg);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, int expirationMinutes, Func<int, TResult> serviceFunction, int intArg)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, DateTimeOffset.Now.AddMinutes(expirationMinutes), serviceFunction, intArg);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTime expirationDate, Func<TResult> serviceFunction)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, new DateTimeOffset(expirationDate), serviceFunction);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTime expirationDate, Func<string, TResult> serviceFunction, string stringArg)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, new DateTimeOffset(expirationDate), serviceFunction, stringArg);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTime expirationDate, Func<long, TResult> serviceFunction, long longArg)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, new DateTimeOffset(expirationDate), serviceFunction, longArg);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTime expirationDate, Func<int, TResult> serviceFunction, int intArg)</div>
<div>
{</div>
<div>
return Load<TResult>(cacheKeyName, new DateTimeOffset(expirationDate), serviceFunction, intArg);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTimeOffset expirationDateOffset, Func<TResult> serviceFunction) </div>
<div>
{</div>
<div>
TResult cachedObject = Load<TResult>(cacheKeyName);</div>
<div>
<br /></div>
<div>
if (cachedObject == null)</div>
<div>
{ </div>
<div>
cachedObject = Save(cacheKeyName, expirationDateOffset, serviceFunction());</div>
<div>
}</div>
<div>
<br /></div>
<div>
return cachedObject;</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTimeOffset expirationDateOffset, Func<string, TResult> serviceFunction, string stringArg)</div>
<div>
{</div>
<div>
TResult cachedObject = Load<TResult>(cacheKeyName);</div>
<div>
<br /></div>
<div>
if (cachedObject == null)</div>
<div>
{</div>
<div>
cachedObject = Save(cacheKeyName, expirationDateOffset, serviceFunction(stringArg));</div>
<div>
}</div>
<div>
<br /></div>
<div>
return cachedObject;</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTimeOffset expirationDateOffset, Func<long, TResult> serviceFunction, long longArg)</div>
<div>
{</div>
<div>
TResult cachedObject = Load<TResult>(cacheKeyName);</div>
<div>
<br /></div>
<div>
if (cachedObject == null)</div>
<div>
{</div>
<div>
cachedObject = Save(cacheKeyName, expirationDateOffset, serviceFunction(longArg));</div>
<div>
}</div>
<div>
<br /></div>
<div>
return cachedObject;</div>
<div>
}</div>
<div>
<br /></div>
<div>
public static TResult Load<TResult>(string cacheKeyName, DateTimeOffset expirationDateOffset, Func<int, TResult> serviceFunction, int intArg)</div>
<div>
{</div>
<div>
TResult cachedObject = Load<TResult>(cacheKeyName);</div>
<div>
<br /></div>
<div>
if (cachedObject == null)</div>
<div>
{</div>
<div>
cachedObject = Save(cacheKeyName, expirationDateOffset, serviceFunction(intArg));</div>
<div>
}</div>
<div>
<br /></div>
<div>
return cachedObject;</div>
<div>
}</div>
<div>
<br /></div>
<div>
}</div>
</div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<h3>
<span style="font-family: inherit;">Example using Func with Caching</span></h3>
<div style="font-family: "Courier New", Courier, monospace;">
The function can be passed in that will fill the data if it does not exist in the cache.</div>
<div style="font-family: "Courier New", Courier, monospace;">
<br /></div>
<div style="font-family: "Courier New", Courier, monospace;">
<div>
[Test]</div>
<div>
public void CacheTestUsingFunc()</div>
<div>
{</div>
<div>
Stopwatch watch = Stopwatch.StartNew();</div>
<div>
string json = Cache.Load<string>("JsonValue", 20, GetJsonFromWebService, "cf4174ce-96d2-495c-b58a-427d35f64a20");</div>
<div>
watch.Stop();</div>
<div>
Console.WriteLine(watch.ElapsedMilliseconds);</div>
<div>
<br /></div>
<div>
watch.Restart();</div>
<div>
json = Cache.Load<string>("JsonValue", 20, GetJsonFromWebService, "cf4174ce-96d2-495c-b58a-427d35f64a20");</div>
<div>
watch.Stop();</div>
<div>
Console.WriteLine(watch.ElapsedMilliseconds);</div>
<div>
}</div>
<div>
<br /></div>
<div>
public string GetJsonFromWebService(string value)</div>
<div>
{</div>
<div>
Thread.Sleep(1000);</div>
<div>
return "{ \"Value\" : \"" + value + "\" }";</div>
<div>
}</div>
</div>
</div>
Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-75169311113250136132017-12-12T15:15:00.004-05:002017-12-12T15:15:56.996-05:00RhinoMocks Resources<h3>
Main Site</h3>
<a href="https://www.hibernatingrhinos.com/oss/rhino-mocks">https://www.hibernatingrhinos.com/oss/rhino-mocks</a><br />
<br />
<a href="https://www.nuget.org/packages/RhinoMocks/3.6.1">https://www.nuget.org/packages/RhinoMocks/3.6.1</a><br />
<br />
<h3>
Videos</h3>
<b><br /></b>
<b>Rhino Mocks Fundamentals</b><br />
<a href="https://www.pluralsight.com/courses/rhinomock-fundamentals">https://www.pluralsight.com/courses/rhinomock-fundamentals</a><br />
<br />
<br />
<h3>
Tutorials</h3>
<b><br /></b>
<b>Unit testing with Mock objects (Rhino Mocks)</b><br />
<a href="https://www.codeproject.com/Articles/686935/Unit-testing-with-Mock-objects-Rhino-Mocks">https://www.codeproject.com/Articles/686935/Unit-testing-with-Mock-objects-Rhino-Mocks</a><br />
<br />
<b>GETTING STARTED WITH RHINO MOCKS (AAA)</b><br />
<a href="https://adamprescott.net/2011/04/07/getting-started-with-rhino-mocks-aaa/">https://adamprescott.net/2011/04/07/getting-started-with-rhino-mocks-aaa/</a><br />
<br />
<b>Using Rhino.Mocks - quick guide to generating mocks and stubs</b><br />
<a href="https://www.wrightfully.com/using-rhino-mocks-quick-guide-to-generating-mocks-and-stubs/">https://www.wrightfully.com/using-rhino-mocks-quick-guide-to-generating-mocks-and-stubs/</a><br />
<br />
<b>TDD : Introduction to Rhino Mocks</b><br />
<a href="http://stephenwalther.com/archive/2008/03/23/tdd-introduction-to-rhino-mocks">http://stephenwalther.com/archive/2008/03/23/tdd-introduction-to-rhino-mocks</a><br />
<br />
<h3>
Cheat Sheets</h3>
<a href="https://www.cheatography.com/gregfinzer/cheat-sheets/rhinomocks/">https://www.cheatography.com/gregfinzer/cheat-sheets/rhinomocks/</a><br />
<br />
<a href="https://ayende.com/wiki/GetFile.aspx?File=Rhino+Mocks+3.3+Quick+Reference.pdf&AspxAutoDetectCookieSupport=1">https://ayende.com/wiki/GetFile.aspx?File=Rhino+Mocks+3.3+Quick+Reference.pdf&AspxAutoDetectCookieSupport=1</a><br />
<br />
<a href="https://lukewickstead.wordpress.com/2013/03/10/rhino-mocks-cheat-sheet/">https://lukewickstead.wordpress.com/2013/03/10/rhino-mocks-cheat-sheet/</a><br />
<br />
<a href="http://www.rulecity.com/browse/rhino.html">http://www.rulecity.com/browse/rhino.html</a>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0tag:blogger.com,1999:blog-5229673538470730199.post-89587410913184134702017-12-06T10:56:00.001-05:002017-12-06T10:58:31.276-05:00SASS ResourcesSASS transpiles into CSS. Here are some resources:<br />
<h3>
<br />MAIN SITE</h3>
<a href="http://sass-lang.com/">http://sass-lang.com/</a><br />
<br />
<h3>
TUTORIALS</h3>
<a href="http://sass-lang.com/guide">http://sass-lang.com/guide</a><br />
<br />
<a href="https://scotch.io/tutorials/getting-started-with-sass">https://scotch.io/tutorials/getting-started-with-sass</a><br />
<br />
<a href="https://www.tutorialspoint.com/sass/">https://www.tutorialspoint.com/sass/</a><br />
<br />
<a href="https://tutorialzine.com/2016/01/learn-sass-in-15-minutes">https://tutorialzine.com/2016/01/learn-sass-in-15-minutes</a><br />
<br />
<br />
<h3>
VIDEOS</h3>
Derek Banas: Learn SASS in One Video<br />
<a href="https://www.youtube.com/watch?v=wz3kElLbEHE">https://www.youtube.com/watch?v=wz3kElLbEHE</a><br />
<br />
Rush through SASS for CSS in 7 Minutes<br />
<a href="https://www.youtube.com/watch?v=pw1DeLy2Xsw">https://www.youtube.com/watch?v=pw1DeLy2Xsw</a><br />
<br />
The NET Ninja: Ninja SASS Course<br />
<a href="https://www.youtube.com/watch?v=St5B7hnMLjg&list=PL4cUxeGkcC9iEwigam3gTjU_7IA3W2WZA">https://www.youtube.com/watch?v=St5B7hnMLjg&list=PL4cUxeGkcC9iEwigam3gTjU_7IA3W2WZA</a><br />
<br />
<h3>
Cheat Sheets</h3>
<a href="https://www.cheatography.com/hamidyfine/cheat-sheets/sass-functions/">https://www.cheatography.com/hamidyfine/cheat-sheets/sass-functions/</a><br />
<br />
<a href="https://www.cheatography.com/mist-graphx/cheat-sheets/sass-script/">https://www.cheatography.com/mist-graphx/cheat-sheets/sass-script/</a>Greg Finzerhttp://www.blogger.com/profile/12920629780529451188noreply@blogger.com0