-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeed.xml
143 lines (126 loc) · 42.5 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://meyer-consulting.net/feed.xml" rel="self" type="application/atom+xml"/><link href="https://meyer-consulting.net/" rel="alternate" type="text/html" hreflang="en"/><updated>2022-05-24T14:53:04-05:00</updated><id>https://meyer-consulting.net/feed.xml</id><title type="html">Robert Meyer Consulting &amp; Training</title><subtitle>Trainer for Mircosoft Azure and Identity/Security. Development from Cloud and Web Solutions.</subtitle><author><name>{"twitter"=>"roeb", "picture"=>"/assets/img/me_free.png"}</name></author><entry><title type="html">SQL Management Studio: Connect and Queries take so long</title><link href="https://meyer-consulting.net/blog/2018/04/16/sql-management-studio-connect-and-queries-take-so-long/" rel="alternate" type="text/html" title="SQL Management Studio: Connect and Queries take so long"/><published>2018-04-16T02:42:50-05:00</published><updated>2018-04-16T02:42:50-05:00</updated><id>https://meyer-consulting.net/blog/2018/04/16/sql-management-studio-connect-and-queries-take-so-long</id><content type="html" xml:base="https://meyer-consulting.net/blog/2018/04/16/sql-management-studio-connect-and-queries-take-so-long/"><![CDATA[<p>When I connect to my local SQL Server using SQL Management Studio or SQL Operations Studio and want to execute queries, it sometimes takes several minutes to execute.</p> <p>This setting in Internet Explorer’s Internet Options solved my problem:</p> <ul> <li>Open Internet Explorer</li> <li>Go to Tools -> Internet option</li> <li>Open the “Advanced” tab</li> <li>Uncheck “Check for server certificate revocation (requires restart)”</li> </ul> <p><img src="/assets/img/blog/2018/1a9c2cf90ff6a62dc42dddcb742a04ac.png" alt="settings"/></p>]]></content><author><name>Robert Meyer</name></author><category term="SQL Server"/><category term="Long Running Queries"/><category term="SQL Management Studio"/><category term="SQL Operations Studio"/><category term="Timeout"/><summary type="html"><![CDATA[When I connect to my local SQL Server using SQL Management Studio or SQL Operations Studio and want to execute queries, it sometimes takes several minutes to execute.]]></summary></entry><entry><title type="html">Git: Add .gitignore after commit</title><link href="https://meyer-consulting.net/blog/2017/10/04/git-add-gitignore-after-commit/" rel="alternate" type="text/html" title="Git: Add .gitignore after commit"/><published>2017-10-04T00:21:30-05:00</published><updated>2017-10-04T00:21:30-05:00</updated><id>https://meyer-consulting.net/blog/2017/10/04/git-add-gitignore-after-commit</id><content type="html" xml:base="https://meyer-consulting.net/blog/2017/10/04/git-add-gitignore-after-commit/"><![CDATA[<p>I had created a new repository in GitHub and forgot to add the .gitignore file to ignore all my Visual Studio and debugging files. However, I did not realize it until after I created the first commit.</p> <p>These are the steps to apply the gitignore file later:</p> <ol> <li>Create a .gitignore file in the root of your local repository. Run this command. This removes everything from the index: <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git <span class="nb">rm</span> <span class="nt">-r</span> <span class="nt">--cached</span> <span class="nb">.</span>
</code></pre></div> </div> </li> <li>Re-add all files. Now the files and folders from gitignore are ignored. <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add <span class="nb">.</span>
</code></pre></div> </div> </li> <li>Then commit the changes again and push it to your GitHub repository <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git commit <span class="nt">-m</span> <span class="s2">".gitignore is now working"</span>
git push
</code></pre></div> </div> </li> </ol>]]></content><author><name>Robert Meyer</name></author><category term="Git"/><category term="GitHub"/><category term="gitignore"/><summary type="html"><![CDATA[I had created a new repository in GitHub and forgot to add the .gitignore file to ignore all my Visual Studio and debugging files. However, I did not realize it until after I created the first commit.]]></summary></entry><entry><title type="html">Self Hosted ASP.NET Core: TagHelper doesn’t work</title><link href="https://meyer-consulting.net/blog/2017/09/29/self-hosted-asp-net-core-taghelper-doesnt-work/" rel="alternate" type="text/html" title="Self Hosted ASP.NET Core: TagHelper doesn’t work"/><published>2017-09-29T00:56:06-05:00</published><updated>2017-09-29T00:56:06-05:00</updated><id>https://meyer-consulting.net/blog/2017/09/29/self-hosted-asp-net-core-taghelper-doesnt-work</id><content type="html" xml:base="https://meyer-consulting.net/blog/2017/09/29/self-hosted-asp-net-core-taghelper-doesnt-work/"><![CDATA[<p>I have implemented a simple TagHelper in a ASP.NET Core 2.0 Website, which replace the <time> Tag with the current time. The website never runs in an ISS or Kestrel server, but is hosted by HttpSys in a console / service.</p> <p>My custom TimeTagHelper:</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="nf">HtmlTargetElement</span><span class="p">(</span><span class="s">"time"</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">TimeTagHelper</span> <span class="p">:</span> <span class="n">TagHelper</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">override</span> <span class="k">async</span> <span class="n">Task</span> <span class="nf">ProcessAsync</span><span class="p">(</span><span class="n">TagHelperContext</span> <span class="n">context</span><span class="p">,</span> <span class="n">TagHelperOutput</span> <span class="n">output</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">output</span><span class="p">.</span><span class="n">Content</span><span class="p">.</span><span class="nf">SetHtmlContent</span><span class="p">(</span><span class="s">$"<h1></span><span class="p">{</span><span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">.</span><span class="nf">ToShortTimeString</span><span class="p">()}</span><span class="s"></h1>"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div> <p>If I start the website project directly, the TagHelper works without problems. Launched from the Console / Service, the <time> tag was not replaced. Obviously the _ViewImports.cshtml is not loaded.</p> <h5 id="the-solutionpreservecompilationcontext">The solution: PreserveCompilationContext</h5> <p>These are the steps that helped me:</p> <ol> <li>Add the following ItemGroup definition to my Selhosted.Website.csproj</li> </ol> <div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><ItemGroup></span>
<span class="nt"><EmbeddedResource</span> <span class="na">Include=</span><span class="s">"wwwroot\**\*;Views\**\*;Areas\**\Views"</span> <span class="nt">/></span>
<span class="nt"></ItemGroup></span>
</code></pre></div></div> <ol> <li>Add the <code>PreserveCompilationContext</code> property to the PropertyGroup in Selhosted.Website.csproj</li> </ol> <div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><PropertyGroup></span>
<span class="nt"><TargetFramework></span>netcoreapp2.0<span class="nt"></TargetFramework></span>
<span class="nt"><AssemblyName></span>SelfHosted.Website<span class="nt"></AssemblyName></span>
<span class="nt"><RootNamespace></span>SelfHosted.Website<span class="nt"></RootNamespace></span>
<span class="nt"><TypeScriptToolsVersion></span>2.3<span class="nt"></TypeScriptToolsVersion></span>
<span class="nt"><PreserveCompilationContext></span>true<span class="nt"></PreserveCompilationContext></span>
<span class="nt"></PropertyGroup></span>
</code></pre></div></div> <ol> <li>Include the generated SelfHosted.Website.deps.json from the websites bin folder to the SelfHosted.Console project and set the Copy to Output Directory to Copy always.</li> </ol> <p><img src="/assets/img/blog/2017/64fcb891c62c3a149c6ff350ebe0b1d3.png" alt="project properties"/></p> <p>You can find the sample project in my GitHub Repo: <a href="https://github.com/roeb/DotNetCoreSamples" target="_blank" rel="noopener">roeb/DotNetCoreSamples</a></p>]]></content><author><name>Robert Meyer</name></author><category term=".NET Core 2.0"/><category term="ASP.NET Core 2.0"/><category term="Web Development"/><category term=".NET Core"/><category term="ASP.NET Core"/><category term="SelfHosted Website"/><category term="TagHelper"/><summary type="html"><![CDATA[I have implemented a simple TagHelper in a ASP.NET Core 2.0 Website, which replace the <time> Tag with the current time. The website never runs in an ISS or Kestrel server, but is hosted by HttpSys in a console / service.]]></summary></entry><entry><title type="html">SelfHosted ASP.NET Core 2.0 Application</title><link href="https://meyer-consulting.net/blog/2017/09/22/selfhosted-asp-net-core-2-0-application/" rel="alternate" type="text/html" title="SelfHosted ASP.NET Core 2.0 Application"/><published>2017-09-22T03:40:14-05:00</published><updated>2017-09-22T03:40:14-05:00</updated><id>https://meyer-consulting.net/blog/2017/09/22/selfhosted-asp-net-core-2-0-application</id><content type="html" xml:base="https://meyer-consulting.net/blog/2017/09/22/selfhosted-asp-net-core-2-0-application/"><![CDATA[<p>Auf Grund einer Projektanforderung musste ich mich die Tage damit auseinandersetzen, wie man eine ASP.NET Core 2.0 Website und Web API in einem eigenen Prozess als Windows Service bereitstellt.</p> <p>Hierbei gibt es einige Besonderheiten zu beachten, auf welche ich in diesem Post gern näher eingehen möchte.</p> <p>Folgende Technologien kommen zum Einsatz:</p> <ul> <li>Alle Projekte basieren auf .NET Core 2.0 oder .NET Standard 2.0</li> <li>Autofac als IoC Container</li> <li>NLog für das Logging</li> <li>Peter Kottas WindowsService als ServerFabric (<a href="https://github.com/PeterKottas/DotNetCore.WindowsService" target="_blank" rel="noopener">GitHub</a>)</li> </ul> <h5 id="grundlegende-architektur-der-anwendung">Grundlegende Architektur der Anwendung</h5> <p><img class=" size-full wp-image-349 aligncenter" src="/assets/img/blog/2017/architecture.png" alt="Architecture" width="790" height="200"/></p> <p>Zu finden ist dieses Beispiel auf <a href="https://github.com/roeb/DotNetCoreSamples" target="_blank" rel="noopener">GitHub</a>.</p> <h5>Grundlegendes Vorgehen</h5> <p>Die Konsolenapplikation kann als WindowsService oder direkt ausgeführt werden und hostet die Website und die API. Die Website und die API sind beides .NETStandard 2.0 Projekte, während die Console eine .NET Core 2.0 Anwendung darstellt.</p> <h5>Aufbau der SelfHosted.Console</h5> <p>IApplication definiert ein Interface zum Starten und Stoppen der Applikationen. Eine Applikation kann eine Website oder eine WebApi sein.</p> <p><img class=" size-full wp-image-357 aligncenter" src="/assets/img/blog/2017/iapplication.png" alt="IApplication" width="429" height="208"/></p> <p>Diese Applikationen werden in Autofac registriert und einem gekapselten MicroService geladen und gestartet.</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">SelfHostedWindowService</span> <span class="p">:</span> <span class="n">MicroService</span><span class="p">,</span> <span class="n">IMicroService</span>
<span class="p">{</span>
<span class="k">private</span> <span class="n">IServiceProvider</span> <span class="n">_provider</span><span class="p">;</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Start</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nf">StartBase</span><span class="p">();</span>
<span class="kt">var</span> <span class="n">builder</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">ContainerBuilder</span><span class="p">();</span>
<span class="n">builder</span><span class="p">.</span><span class="n">RegisterType</span><span class="p"><</span><span class="n">WebApplication</span><span class="p">>().</span><span class="n">As</span><span class="p"><</span><span class="n">IApplication</span><span class="p">>();</span>
<span class="n">builder</span><span class="p">.</span><span class="n">RegisterType</span><span class="p"><</span><span class="n">WebApiApplication</span><span class="p">>().</span><span class="n">As</span><span class="p"><</span><span class="n">IApplication</span><span class="p">>();</span>
<span class="kt">var</span> <span class="n">applicationContainer</span> <span class="p">=</span> <span class="n">builder</span><span class="p">.</span><span class="nf">Build</span><span class="p">();</span>
<span class="n">_provider</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">AutofacServiceProvider</span><span class="p">(</span><span class="n">applicationContainer</span><span class="p">);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">app</span> <span class="k">in</span> <span class="n">_provider</span><span class="p">.</span><span class="n">GetServices</span><span class="p"><</span><span class="n">IApplication</span><span class="p">>())</span>
<span class="p">{</span>
<span class="n">app</span><span class="p">.</span><span class="nf">Start</span><span class="p">();</span>
<span class="p">}</span>
<span class="n">System</span><span class="p">.</span><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Windows services started."</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Stop</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nf">StopBase</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">app</span> <span class="k">in</span> <span class="n">_provider</span><span class="p">.</span><span class="n">GetServices</span><span class="p"><</span><span class="n">IApplication</span><span class="p">>())</span>
<span class="p">{</span>
<span class="n">app</span><span class="p">.</span><span class="nf">Stop</span><span class="p">();</span>
<span class="p">}</span>
<span class="n">System</span><span class="p">.</span><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Windows services stopped."</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div> <p>Beim Starten der Konsole oder des Services, wird der MicroService registriert und in einer ServiceFactory geladen. Dadurch starten alle Applikationen, welche in den jeweiligen MicroService definiert sind.</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ServiceRunner</span><span class="p"><</span><span class="n">SelfHostedWindowService</span><span class="p">>.</span><span class="nf">Run</span><span class="p">(</span><span class="n">config</span> <span class="p">=></span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">serviceName</span> <span class="p">=</span> <span class="s">"SelfHosted.WindowsService"</span><span class="p">;</span>
<span class="n">config</span><span class="p">.</span><span class="nf">SetName</span><span class="p">(</span><span class="n">serviceName</span><span class="p">);</span>
<span class="n">config</span><span class="p">.</span><span class="nf">Service</span><span class="p">(</span><span class="n">serviceConfig</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">serviceConfig</span><span class="p">.</span><span class="nf">ServiceFactory</span><span class="p">((</span><span class="n">service</span><span class="p">,</span> <span class="n">extraArguments</span><span class="p">)</span> <span class="p">=></span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">SelfHostedWindowService</span><span class="p">();</span>
<span class="p">});</span>
<span class="n">serviceConfig</span><span class="p">.</span><span class="nf">OnStart</span><span class="p">((</span><span class="n">service</span><span class="p">,</span> <span class="n">extraArguments</span><span class="p">)</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Service {0} started"</span><span class="p">,</span> <span class="n">serviceName</span><span class="p">);</span>
<span class="n">service</span><span class="p">.</span><span class="nf">Start</span><span class="p">();</span>
<span class="p">});</span>
<span class="n">serviceConfig</span><span class="p">.</span><span class="nf">OnStop</span><span class="p">((</span><span class="n">service</span><span class="p">)</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Service {0} stopped"</span><span class="p">,</span> <span class="n">serviceName</span><span class="p">);</span>
<span class="n">service</span><span class="p">.</span><span class="nf">Stop</span><span class="p">();</span>
<span class="p">});</span>
<span class="n">serviceConfig</span><span class="p">.</span><span class="nf">OnError</span><span class="p">(</span><span class="n">e</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">$"Service '</span><span class="p">{</span><span class="n">serviceName</span><span class="p">}</span><span class="s">' errored with exception : </span><span class="p">{</span><span class="n">e</span><span class="p">.</span><span class="n">Message</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div> <h5>Besonderheiten in der ASP.NET Core 2.0 Website</h5> <p>Es gibt jedoch beim hosten seiner ASP.NET Core 2.0 Website in einer Console noch drei wichtige Dinge zu beachten.</p> <ol> <li>Alle Views müssen Embedded werden. Dafür habe ich folgende Extension Methode geschrieben, welche im Startup bei AddRazorOptions aufgerufen wird.<br/></li> </ol> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">RazorViewEngineOptions</span> <span class="nf">AddViews</span><span class="p">(</span><span class="k">this</span> <span class="n">RazorViewEngineOptions</span> <span class="n">options</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="n">FileProviders</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="k">new</span> <span class="nf">EmbeddedFileProvider</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">ServiceCollectionExtensions</span><span class="p">).</span><span class="nf">GetTypeInfo</span><span class="p">().</span><span class="n">Assembly</span><span class="p">,</span> <span class="s">"SelfHosted.Website"</span><span class="p">));</span>
<span class="k">return</span> <span class="n">options</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <p>2. Danach stellte sich heraus, dass noch einige Assemblies fehlten. Diese werden ebenfalls per Extension Methode im Startup geladen.<br/></p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">RazorViewEngineOptions</span> <span class="nf">AddCompilationAssemblies</span><span class="p">(</span><span class="k">this</span> <span class="n">RazorViewEngineOptions</span> <span class="n">options</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">var</span> <span class="n">myAssemblies</span> <span class="p">=</span> <span class="n">AppDomain</span>
<span class="p">.</span><span class="n">CurrentDomain</span>
<span class="p">.</span><span class="nf">GetAssemblies</span><span class="p">()</span>
<span class="p">.</span><span class="nf">Where</span><span class="p">(</span><span class="n">x</span> <span class="p">=></span> <span class="p">!</span><span class="n">x</span><span class="p">.</span><span class="n">IsDynamic</span><span class="p">)</span>
<span class="p">.</span><span class="nf">Concat</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="c1">// additional assemblies used in Razor pages:</span>
<span class="k">typeof</span><span class="p">(</span><span class="n">HtmlString</span><span class="p">).</span><span class="n">Assembly</span><span class="p">,</span> <span class="c1">// Microsoft.AspNetCore.Html.Abstractions</span>
<span class="k">typeof</span><span class="p">(</span><span class="n">IViewLocalizer</span><span class="p">).</span><span class="n">Assembly</span><span class="p">,</span> <span class="c1">// Microsoft.AspNetCore.Mvc.Localization</span>
<span class="k">typeof</span><span class="p">(</span><span class="n">IRequestCultureFeature</span><span class="p">).</span><span class="n">Assembly</span> <span class="c1">// Microsoft.AspNetCore.Localization</span>
<span class="p">})</span>
<span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">x</span> <span class="p">=></span> <span class="n">MetadataReference</span><span class="p">.</span><span class="nf">CreateFromFile</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">Location</span><span class="p">))</span>
<span class="p">.</span><span class="nf">ToArray</span><span class="p">();</span>
<span class="kt">var</span> <span class="n">previous</span> <span class="p">=</span> <span class="n">options</span><span class="p">.</span><span class="n">CompilationCallback</span><span class="p">;</span>
<span class="n">options</span><span class="p">.</span><span class="n">CompilationCallback</span> <span class="p">=</span> <span class="n">context</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">previous</span><span class="p">?.</span><span class="nf">Invoke</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
<span class="n">context</span><span class="p">.</span><span class="n">Compilation</span> <span class="p">=</span> <span class="n">context</span><span class="p">.</span><span class="n">Compilation</span><span class="p">.</span><span class="nf">AddReferences</span><span class="p">(</span><span class="n">myAssemblies</span><span class="p">);</span>
<span class="p">};</span>
<span class="k">return</span> <span class="n">options</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <ol> <li>Jetzt müssen noch alle statischen Files, welche z.B. im wwwroot liegen embedded werden. Auch hier gibt es wieder eine passende Extension Methode.<br/></li> </ol> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IServiceCollection</span> <span class="nf">AddStaticFiles</span><span class="p">(</span><span class="k">this</span> <span class="n">IServiceCollection</span> <span class="n">collection</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// static files are embedded resources in the "wwwroot" folder</span>
<span class="n">collection</span><span class="p">.</span><span class="n">Configure</span><span class="p"><</span><span class="n">StaticFileOptions</span><span class="p">>(</span><span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="n">FileProvider</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">EmbeddedFileProvider</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">Startup</span><span class="p">).</span><span class="n">Assembly</span><span class="p">,</span> <span class="k">typeof</span><span class="p">(</span><span class="n">Startup</span><span class="p">).</span><span class="n">Namespace</span> <span class="p">+</span> <span class="s">".wwwroot"</span><span class="p">);</span>
<span class="p">});</span>
<span class="k">return</span> <span class="n">collection</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <p>Aufgerufen werden die Extension Methods im Startup der Website, in der Funktion ConfigureServices wie folgt:</p> <div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="n">IServiceProvider</span> <span class="nf">ConfigureServices</span><span class="p">(</span><span class="n">IServiceCollection</span> <span class="n">services</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">services</span><span class="p">.</span><span class="n">AddSingleton</span><span class="p"><</span><span class="n">IConfiguration</span><span class="p">>(</span><span class="n">Configuration</span><span class="p">);</span>
<span class="n">services</span><span class="p">.</span><span class="nf">AddMvc</span><span class="p">()</span>
<span class="p">.</span><span class="nf">AddRazorOptions</span><span class="p">(</span><span class="n">options</span> <span class="p">=></span>
<span class="p">{</span>
<span class="n">options</span><span class="p">.</span><span class="nf">AddViews</span><span class="p">();</span>
<span class="n">options</span><span class="p">.</span><span class="nf">AddCompilationAssemblies</span><span class="p">();</span>
<span class="p">});</span>
<span class="n">services</span><span class="p">.</span><span class="nf">AddStaticFiles</span><span class="p">();</span>
<span class="kt">var</span> <span class="n">builder</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">ContainerBuilder</span><span class="p">();</span>
<span class="n">builder</span><span class="p">.</span><span class="nf">Populate</span><span class="p">(</span><span class="n">services</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="n">ApplicationContainer</span> <span class="p">=</span> <span class="n">builder</span><span class="p">.</span><span class="nf">Build</span><span class="p">();</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">AutofacServiceProvider</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">ApplicationContainer</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div> <h5>Zusammenfassung</h5> <p>Auf diesem Weg erreicht man eine sehr leichtgewichtige Anwendung, welche komplett in einem eigenen Prozess unabhängig von dem Betriebssystem und Webserver installiert werden kann. Somit erreicht man bei seiner Produktentwicklung, welchen bei Kunden vor Ort installiert werden muss, eine sehr hohe Flexibilität und ich unabhängig der Umgebung.</p>]]></content><author><name>Robert Meyer</name></author><category term=".NET"/><category term=".NET Core 2.0"/><category term=".NET Standard 2.0"/><category term="ASP.NET Core 2.0"/><category term="Micro Services"/><category term=".NET Core"/><category term=".NET Standard"/><category term="Autofac"/><category term="NLog"/><category term="SelfHosted Website"/><category term="ServerFabric"/><category term="Windows Service"/><summary type="html"><![CDATA[Auf Grund einer Projektanforderung musste ich mich die Tage damit auseinandersetzen, wie man eine ASP.NET Core 2.0 Website und Web API in einem eigenen Prozess als Windows Service bereitstellt.]]></summary></entry><entry><title type="html">SQL Server 2012: EOMONTH Funktion</title><link href="https://meyer-consulting.net/blog/2012/08/07/sql-server-2012-eomonth-funktion/" rel="alternate" type="text/html" title="SQL Server 2012: EOMONTH Funktion"/><published>2012-08-07T06:18:03-05:00</published><updated>2012-08-07T06:18:03-05:00</updated><id>https://meyer-consulting.net/blog/2012/08/07/sql-server-2012-eomonth-funktion</id><content type="html" xml:base="https://meyer-consulting.net/blog/2012/08/07/sql-server-2012-eomonth-funktion/"><![CDATA[<p>Mit dem SQL Server 2012 ist eine neue Datumsfunktion dazu gekommen. Mit EOMONTH ist es möglich sich den letzten Tag des Monats ausgeben zu lassen. Dies ist besonders interessant wenn man Wertebereiche innerhalb eines Monats oder über mehrere Monate Tag genau selektieren möchte.</p> <p>So wendet man EOMONTH an, um sich den letzten Tag des Monats August im Jahr 2012 ausgegeben zu lassen:</p> <p><img src="/assets/img/blog/2012/eomonth_1.png" alt="settings"/></p> <p>Man kann jedoch auch Monat dazu addieren oder abziehen. Hierfür steht ein optionaler Operator zur Verfügung.</p> <p><img src="/assets/img/blog/2012/eomonth_2.png" alt="settings"/></p> <p>Es ist nur eine kleiner Erweiterung, aber sie erleichtert doch auf angenehme Art die Arbeit mit TSQL.</p>]]></content><author><name>Robert Meyer</name></author><category term="SQL Server"/><category term="EOMONTH"/><category term="SQL Server 2012"/><summary type="html"><![CDATA[Mit dem SQL Server 2012 ist eine neue Datumsfunktion dazu gekommen. Mit EOMONTH ist es möglich sich den letzten Tag des Monats ausgeben zu lassen. Dies ist besonders interessant wenn man Wertebereiche innerhalb eines Monats oder über mehrere Monate Tag genau selektieren möchte.]]></summary></entry><entry><title type="html">“Add STS Reference” in Visual Studio 2012</title><link href="https://meyer-consulting.net/blog/2012/07/30/add-sts-reference-in-visual-studio-2012/" rel="alternate" type="text/html" title="“Add STS Reference” in Visual Studio 2012"/><published>2012-07-30T04:57:43-05:00</published><updated>2012-07-30T04:57:43-05:00</updated><id>https://meyer-consulting.net/blog/2012/07/30/add-sts-reference-in-visual-studio-2012</id><content type="html" xml:base="https://meyer-consulting.net/blog/2012/07/30/add-sts-reference-in-visual-studio-2012/"><![CDATA[<p>Ich habe heute ein Azure Projekt im neuen Visual Studio 2012 angefangen und wollte ACS einbinden. Bei Visual Studio 2010 ging dies sehr einfach über den Menupunkt “Add STS Reference …”.</p> <p><img src="/assets/img/blog/2012/sts_1.png" alt=""/></p> <p>Dieser ist jedoch leider bei Visual Studio 2012 nicht vorhanden. Hier führt es auch nicht zum gewünschten Erfolg, wenn man das aktuelle Azure SDK installiert. Jedoch ist es über einen Umweg möglich die vermisste Funktionalität in Visual Studio 2012 wieder herbei zu zaubern.</p> <ol> <li> <p>Im Hauptmenu von Visual Studio 2012 im Eintrag “Tools” auf den Menupunkt “Extensions and Updates …” klicken. <br/> <img src="/assets/img/blog/2012/sts_2.png" alt=""/></p> </li> <li> <p>In dem sich nun öffnenden Fenster im linken Menu die Kategorie “Online” auswählen und in das Suchfeld “Identity” eingeben. Danach die “Identity and Access Tools” herunterladen und installieren und Visual Studio 2012 neustarten. <img src="/assets/img/blog/2012/sts_3.png" alt=""/></p> </li> <li> <p>Nach dem Neustart von Visual Studio 2012 gibt es einen neuen Menueintrag im Kontextmenu des Projektes mit der Bezeichnung “Identity and Access …”. Hier kann nun wie gewohnt eine ACS Referenz hinzugefügt werden. <br/> <img src="/assets/img/blog/2012/sts_4.png" alt=""/></p> </li> </ol> <p><img src="/assets/img/blog/2012/sts_5.png" alt=""/></p>]]></content><author><name>Robert Meyer</name></author><category term="Azure"/><category term="Visual Studio 2012"/><category term="ACS"/><category term="Reference"/><category term="STS"/><category term="Visual Studio"/><summary type="html"><![CDATA[Ich habe heute ein Azure Projekt im neuen Visual Studio 2012 angefangen und wollte ACS einbinden. Bei Visual Studio 2010 ging dies sehr einfach über den Menupunkt “Add STS Reference …”.]]></summary></entry><entry><title type="html">Paging mit OFFSET und FETCH im SQL Server 2012</title><link href="https://meyer-consulting.net/blog/2012/07/19/pagging-mit-offset-und-fetch-im-sql-server-2012/" rel="alternate" type="text/html" title="Paging mit OFFSET und FETCH im SQL Server 2012"/><published>2012-07-19T00:25:45-05:00</published><updated>2012-07-19T00:25:45-05:00</updated><id>https://meyer-consulting.net/blog/2012/07/19/pagging-mit-offset-und-fetch-im-sql-server-2012</id><content type="html" xml:base="https://meyer-consulting.net/blog/2012/07/19/pagging-mit-offset-und-fetch-im-sql-server-2012/"><![CDATA[<p>Lange hat es gedauert, doch nun beherrscht der SQL Server mit Version 2012 endlich das Paging. Unter Paging versteht man die Festlegung davon wie viele Datensätze pro Seite ausgeben werden sollen. Dies wird besonders bei diversen Webapplikationen benötigt um die Anzahl der geladenen Daten zu verringern.</p> <p>Würde die Suche auf einer Website ein Trefferergebnis von 400 Datensätzen betragen, möchte der Nutzer sicherlich nicht alle 400 Datensätze mit einmal auf der Website sehen, sondern z.B. immer nur 20 Stück. Diese 20 Datensätze werden jetzt auf 20 Seiten aufgelistet. Damit der Traffic möglichst gering bleibt, werden auch immer nur die Datensätze der aktuellen Seite geladen. Das nennt man Paging.</p> <h5 id="möglichkeiten-mit-dem-sql-server-2012">Möglichkeiten mit dem SQL Server 2012</h5> <p>Mit dem SQL Server 2012 kommen unter anderen zwei neue Befehle welche in der ORDER BY Klausel genutzt werden können:</p> <ul> <li> <p><strong>OFFSET</strong><br/> Legt fest wie viele Datensätze übersprungen werden, bevor Datensätze zurückgegeben werden.</p> </li> <li> <p><strong>FETCH</strong><br/> Gibt an wie viele Datensätze nach der OFFSET Klausel angezeigt werden sollen</p> </li> </ul> <h5 id="beispiel">Beispiel</h5> <p>In dem Beispiel werden Kundendaten selektiert, welche mit dem Nachnamen Meyer beginnen. Allerdings werden die ersten 40 Zeilen übersprungen und von da an 20 Zeilen selektiert.</p> <p><img src="/assets/img/blog/2012/offset_1.png" alt=""/></p> <h5 id="varianten-von-offset-und-fetch">Varianten von OFFSET und FETCH</h5> <p>Anstelle von NEXT kann man auch FIRST genutzt werden, es handelt sich hierbei nur um ein Synonym. Das gleich gilt für das Wort ROWS, hier kann auch ROW genutzt werden. Anstelle der direkten Anzahl der Datensätze bei OFFSET oder FETCH kann hier auch eine Variable zum Einsatz kommen. Dies könnte zum Beispiel so aussehen und wäre im zusammenhangen mit dynamisches Stored Procedures recht interessant.</p> <p><img src="/assets/img/blog/2012/offset_2.png" alt=""/></p> <h5 id="expressions-in-offset-und-fetch">Expressions in OFFSET und FETCH</h5> <p>Es ist ebenfalls möglich Expressions im Zusammenhang von OFFSET und FETCH zu nutzen. Hier ein Beispiel:</p> <p><img src="/assets/img/blog/2012/offset_3.png" alt=""/></p> <p>Zur Verfügung stehen die Erweiterungen OFFSET und FETCH bereits ab dem SQL Server 2012 Express.</p>]]></content><author><name>Robert Meyer</name></author><category term="SQL Server"/><category term="FETCH"/><category term="OFFSET"/><category term="ORDER BY"/><category term="ROW_NUMBER"/><category term="SQL Server 2012"/><category term="TOP"/><summary type="html"><![CDATA[Lange hat es gedauert, doch nun beherrscht der SQL Server mit Version 2012 endlich das Paging. Unter Paging versteht man die Festlegung davon wie viele Datensätze pro Seite ausgeben werden sollen. Dies wird besonders bei diversen Webapplikationen benötigt um die Anzahl der geladenen Daten zu verringern.]]></summary></entry><entry><title type="html">Neuerungen mit SharePoint 2013</title><link href="https://meyer-consulting.net/blog/2012/07/17/neuerungen-mit-sharepoint-2013/" rel="alternate" type="text/html" title="Neuerungen mit SharePoint 2013"/><published>2012-07-17T01:59:37-05:00</published><updated>2012-07-17T01:59:37-05:00</updated><id>https://meyer-consulting.net/blog/2012/07/17/neuerungen-mit-sharepoint-2013</id><content type="html" xml:base="https://meyer-consulting.net/blog/2012/07/17/neuerungen-mit-sharepoint-2013/"><![CDATA[<p>Diese Nacht war es endlich soweit und die Microsoft SharePoint 2013 Preview stand, neben Office 2013, zum Download bereit. Natürlich bringt SharePoint 2013 viele neue Features mit. Mit einigen hat man gerechnet, andere kamen ziemlich überraschend. Ich möchte euch hier eine kurze Auflistung der neuen Features zur Verfügung stellen.</p> <ul> <li><strong>.NET 4.0 mit SharePoint 2013</strong></li> <li><strong>Workflow Foundation 4.0</strong></li> <li><strong>SharePoint Marketplace for Apps</strong> <br/> Mit SharePoint 2013 führt Microsoft den Marketplace für SharePoint Apps ein. Eine SharePoint App ist eine Webapplikation, welche in SharePoint eingebunden werden kann. Hier ist man in der Wahl der Technologie relativ frei und kann z.B. HTML 5, CSS und JavaScript nutzen. Hierzu gibt es im Object Modell auf der Ebene von SPWeb eine Erweiterung mit dem Namen SPApp.</li> <li><strong>Stärkere Integration der Office Produkte in SharePoint 2013</strong></li> <li><strong>Verbesserung in Client Object Model</strong> <br/> Das Client Object Model wurde mit der Möglichkeit der Suche erweitert. Somit ist es nun auch Möglich über das Client Object Model die in SharePoint integrierte Suche zu nutzen.</li> <li><strong>Verbesserung der Workflows über den SharePoint Designer</strong> <br/> Es ist nun Möglich dass bei Workflows, welche über den SharePoint Designer erstellt werden, Schleifen eingesetzt werden können. Dies ging bisher bei SharePoint 2010 nur bei Workflows die mit Visual Studio erstellt wurden.</li> <li><strong>Anstelle von AJAX kommt nun HTML5 mit JQuery zum Einsatz</strong></li> <li><strong>MinimaDownload Strategy (MDS)</strong> <br/> MDS ist eine Erweiterung die Microsoft dem SharePoint Server 2013 spendiert hat, mit der es Möglich ist nur den veränderten Bereich von Webseiten zu übertragen. Das Ziel ist den Traffic möglichst gering zu halten und die Geschwindigkeit bei Nutzern mit geringer Bandbreite zu erhöhen.</li> <li><strong>OAuth 2.0 Authentication</strong> <br/> Unterstützung von WIndows Live ID, Twitter oder Facebook.</li> <li><strong>Unterstützung von Visual Studio 2012</strong></li> </ul> <p>Herunterladen kann man sich SharePoint 2013 Foundation kostenlos auf der Seite von <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30345">Microsoft</a>. Wer eine MSDN Subscription besitzt, kann sich die größeren Versionen dort herunterladen.</p> <p>Viel Spaß beim Ausprobieren!</p>]]></content><author><name>Robert Meyer</name></author><category term="SharePoint"/><category term="Features"/><category term="Neuerungen"/><category term="SharePoint 2013"/><summary type="html"><![CDATA[Diese Nacht war es endlich soweit und die Microsoft SharePoint 2013 Preview stand, neben Office 2013, zum Download bereit. Natürlich bringt SharePoint 2013 viele neue Features mit. Mit einigen hat man gerechnet, andere kamen ziemlich überraschend. Ich möchte euch hier eine kurze Auflistung der neuen Features zur Verfügung stellen.]]></summary></entry><entry><title type="html">Update auf große Datenmengen mit @@ROWCOUNT</title><link href="https://meyer-consulting.net/blog/2012/07/11/update-auf-groe-datenmengen-mit-rowcount/" rel="alternate" type="text/html" title="Update auf große Datenmengen mit @@ROWCOUNT"/><published>2012-07-11T03:38:31-05:00</published><updated>2012-07-11T03:38:31-05:00</updated><id>https://meyer-consulting.net/blog/2012/07/11/update-auf-groe-datenmengen-mit-rowcount</id><content type="html" xml:base="https://meyer-consulting.net/blog/2012/07/11/update-auf-groe-datenmengen-mit-rowcount/"><![CDATA[<p>Häufig steht man vor der Herausforderung in einer sehr großen Tabelle Datensätze zu aktualisieren. Hat diese z.B. wie in meinem Szenario über 10 Millionen Datensätze und einen Trigger der auf Update Commands reagiert, ist es nicht sehr sinnvoll mit einem mal mehr als 1000 Zeilen zu aktualisieren. Hierbei kann es zu ungewollten Table Locks kommen. Noch problematischer wird es, wenn während des Zeitpunktes des Updates viele Abfragen auf dieser Tabelle ausgeführt werden.</p> <p>Der erste Lösungsansatz bei diesem Problem ist ein eingeschränkter Update Befehl auf 1000 Zeilen. Diese kann man mit einem UPDATE TOP (1000) und ebenso mit dem Befehl SET ROWCOUNT 1000 erreichen (Siehe Beispiele).</p> <p><img src="/assets/img/blog/2012/row_count_1.png" alt=""/></p> <p>Möchte man nun etwa 100000 Zeilen aktualisieren empfiehlt es sich hierfür eine Schleife zu bauen. Außerdem sollte nach jedem Updatebefehl eine Wartezeit von 1-3 Sekunden eingefügt werden, damit andere Anfragen die Möglichkeit haben Sperren zu setzen. Dies erreicht man durch den Befehl WAITFOR DELAY. Hier ein Beispiel:</p> <p><img src="/assets/img/blog/2012/row_count_2.png" alt=""/></p> <p>Der gesamte Updatevorgang kann dadurch etwas länger dauern, man minimiert jedoch die Wahrscheinlichkeit von Locks über die ganze Tabelle und erlaubt z.B. Triggern optimaler zu arbeiten.</p>]]></content><author><name>Robert Meyer</name></author><category term="SQL Server"/><category term="ROWCOUNT"/><category term="UPDATE"/><category term="WAITFOR DELAY"/><summary type="html"><![CDATA[Häufig steht man vor der Herausforderung in einer sehr großen Tabelle Datensätze zu aktualisieren. Hat diese z.B. wie in meinem Szenario über 10 Millionen Datensätze und einen Trigger der auf Update Commands reagiert, ist es nicht sehr sinnvoll mit einem mal mehr als 1000 Zeilen zu aktualisieren. Hierbei kann es zu ungewollten Table Locks kommen. Noch problematischer wird es, wenn während des Zeitpunktes des Updates viele Abfragen auf dieser Tabelle ausgeführt werden.]]></summary></entry></feed>