<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Amir Ismail</title>
    <description>The latest articles on Forem by Amir Ismail (@miroprocessor).</description>
    <link>https://forem.com/miroprocessor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F342473%2Fc6ede57c-bc20-4b82-babb-74b256429dc5.jpg</url>
      <title>Forem: Amir Ismail</title>
      <link>https://forem.com/miroprocessor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/miroprocessor"/>
    <language>en</language>
    <item>
      <title>DotVVM Controls : GridView</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Wed, 22 Jul 2020 22:06:46 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-controls-gridview-1gjh</link>
      <guid>https://forem.com/dotvvm/dotvvm-controls-gridview-1gjh</guid>
      <description>&lt;p&gt;GridView control in DotVVM is very similar to what we used to use in our legacy web forms applications. When you run your DotVVM application, it is getting rendered as a classic HTML table.&lt;/p&gt;

&lt;p&gt;In DotVVM, you can bind your &lt;code&gt;GridView&lt;/code&gt; control by setting &lt;code&gt;DataSource&lt;/code&gt; property to &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;GridViewDataSet&amp;lt;T&amp;gt;&lt;/code&gt; object. GridView Control in DotVVM supports inline editing, sorting and defining your column template.&lt;/p&gt;

&lt;h4&gt;
  
  
  Simple GridView
&lt;/h4&gt;

&lt;p&gt;Suppose we want to display a list of students.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime EnrollmentDate { get; set; }
}    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in ViewModel class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public List&amp;lt;Student&amp;gt; Students { get; set; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in dothtml file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:GridView DataSource="{value: Students}" class="page-grid"&amp;gt;
    &amp;lt;Columns&amp;gt;
         &amp;lt;dot:GridViewTextColumn ValueBinding="{value: FirstName}" HeaderText="First Name" /&amp;gt;
         &amp;lt;dot:GridViewTextColumn ValueBinding="{value: LastName}" HeaderText="Last Name" /&amp;gt;
         &amp;lt;dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}" HeaderText="Enrollment Date" /&amp;gt;
    &amp;lt;/Columns&amp;gt;
&amp;lt;/dot:GridView&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we used &lt;code&gt;GridViewTextColumn&lt;/code&gt; for all fields and used &lt;code&gt;ValueBinding&lt;/code&gt; attribute to specify which property is going to be rendered in that column. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fflf7djiuf7f8uaew6bnh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fflf7djiuf7f8uaew6bnh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By Default DotVVM is getting the string representation of the specified value and render it.&lt;/p&gt;
&lt;h4&gt;
  
  
  FormatString
&lt;/h4&gt;

&lt;p&gt;To specify a specific format for the rendered value, we can do that by setting &lt;code&gt;FormatString&lt;/code&gt; of the target column. DotVVM is supporting most of .Net format strings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}" 
 FormatString="yyyy-MM-dd" 
 HeaderText="Enrollment Date" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd60ug9pauawij4gkecbt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd60ug9pauawij4gkecbt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Inline Editing
&lt;/h4&gt;

&lt;p&gt;In the past when we tried to implement inline editing for a GridView in web forms application we had had to write many lines of code and implement Edit event but in DotVVM it pretty easy to implement it with only one limitation, your data source should be of type &lt;code&gt;GridViewDataSet&amp;lt;T&amp;gt;&lt;/code&gt;. &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is not supported for inline editing.&lt;/p&gt;

&lt;p&gt;In ViewModel class change the Students property type and Set &lt;code&gt;RowEditOptions.PrimaryKeyPropertyName&lt;/code&gt; to your list unique key(in our case is &lt;code&gt;Id&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public GridViewDataSet&amp;lt;Student&amp;gt; Students { get; set; } = new GridViewDataSet&amp;lt;StudentListModel&amp;gt;()
   {
      RowEditOptions = { PrimaryKeyPropertyName = "Id" }
   };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;PreRender&lt;/code&gt; method populate your &lt;code&gt;GridViewDataSet&amp;lt;Student&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public override async Task PreRender()
{
     if (Students.IsRefreshRequired)
     {
         var queryable = await _studentService.GetAllStudentsAsync();
         Students.LoadFromQueryable(queryable.AsQueryable());
     }
     await base.PreRender();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in dothtml file, set &lt;code&gt;InlineEditing&lt;/code&gt; attribute of your GridView to &lt;code&gt;true&lt;/code&gt;. By default DotVVM is allowing all columns to be editable. If you want to prevent a specific column to be edited you need to set its &lt;code&gt;IsEditable&lt;/code&gt; attribute to &lt;code&gt;false&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:GridView DataSource="{value: Students}" class="page-grid" InlineEditing="true"&amp;gt;
  &amp;lt;Columns&amp;gt;
    &amp;lt;dot:GridViewTextColumn ValueBinding="{value: FirstName}" HeaderText="First Name" /&amp;gt;
    &amp;lt;dot:GridViewTextColumn ValueBinding="{value: LastName}" HeaderText="Last Name" /&amp;gt;
    &amp;lt;dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}"
       IsEditable="false"
       HeaderText="Enrollment Date" FormatString="yyyy-MM-dd" /&amp;gt;
    &amp;lt;dot:GridViewTemplateColumn&amp;gt;
        &amp;lt;ContentTemplate&amp;gt;
           &amp;lt;dot:Button class Text="Edit" Click="{command: _parent.Edit(_this)}" /&amp;gt;
        &amp;lt;/ContentTemplate&amp;gt;
        &amp;lt;EditTemplate&amp;gt;
           &amp;lt;dot:Button Text="Save" Click="{command: _parent.Update(_this)}" /&amp;gt;
           &amp;lt;dot:Button Text="Cancel" Click="{command: _parent.Cancel()}" /&amp;gt;
        &amp;lt;/EditTemplate&amp;gt;
    &amp;lt;/dot:GridViewTemplateColumn&amp;gt;
  &amp;lt;/Columns&amp;gt;  
&amp;lt;/dot:GridView&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We added a&lt;code&gt;GridViewTemplateColumn&lt;/code&gt; and specified its &lt;code&gt;ContentTemplate&lt;/code&gt; which will be rendered in normal display &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffjko72wdov3c5l97eacy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffjko72wdov3c5l97eacy.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
and &lt;code&gt;EditTemplate&lt;/code&gt; which will be rendered when we click Edit button &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5drqna12eyz2a351y7me.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5drqna12eyz2a351y7me.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_parent&lt;/code&gt; is instance of your model object and &lt;code&gt;_this&lt;/code&gt; which is passed to &lt;code&gt;Edit&lt;/code&gt; and &lt;code&gt;Update&lt;/code&gt; Methods is the corresponding item in GridView data source.&lt;/p&gt;

&lt;p&gt;in ModelView class we need to add the commands (normal c# method) that will be executed when the user click on Edit, Save, and cancel buttons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void Edit(Student student)
{
     Students.RowEditOptions.EditRowId = student.Id;
}
public void Cancel()
{
     Students.RowEditOptions.EditRowId = null;
     Students.RequestRefresh();
}
public void Update(StudentListModel model)
{
     // code for updating your datastore
     .....
     Students.RowEditOptions.EditRowId = null;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;When you do inline editing, DotVVM does't refresh the whole page, but it do it via ajax calls.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Nested GridViews
&lt;/h4&gt;

&lt;p&gt;Suppose we want to display student grades in the same row besides his Name. to achieve this, the Student Object should contains a property if type &lt;code&gt;GridViewDataSet&lt;/code&gt; for grades List. Then in &lt;code&gt;Prerender()&lt;/code&gt; method populate that property for each Student object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public override async Task PreRender()
{
     if (Students.IsRefreshRequired)
     {
         var queryable = await _studentService.GetAllStudentsAsync();
         queryable.ForEach(x =&amp;gt;
         {
             x.Grades = new GridViewDataSet&amp;lt;Grade&amp;gt;()
             {
                RowEditOptions = { PrimaryKeyPropertyName = "GradeId" }
             };                 
             x.Grades.LoadFromQueryable(x.StudentGrades.AsQueryable());
         });
         Students.LoadFromQueryable(queryable.AsQueryable());
     }
     await base.PreRender();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in dothtml file will add a new GridViewTemplateColumn for the inner GridView&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:GridViewTemplateColumn HeaderText="Grades" IsEditable="false"&amp;gt;
     &amp;lt;dot:GridView DataSource="{value: Grades}" class="page-grid"&amp;gt;
          &amp;lt;Columns&amp;gt;
              &amp;lt;dot:GridViewTextColumn ValueBinding="{value: Subject}" HeaderText="Subject" /&amp;gt;
              &amp;lt;dot:GridViewTextColumn ValueBinding="{value: Month}" HeaderText="Month" /&amp;gt;
              &amp;lt;dot:GridViewTextColumn ValueBinding="{value: Score}" HeaderText="Score" /&amp;gt;                            
          &amp;lt;/Columns&amp;gt;
     &amp;lt;/dot:GridView&amp;gt;
&amp;lt;/dot:GridViewTemplateColumn&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5vz98dkv4nj4y5zwcdn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5vz98dkv4nj4y5zwcdn6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In this article we demonstrated how to use DotVVM GridView control and how it is pretty easy to bind your collection to it, enable inline editing without re-loading the whole page and how to render nested GridViews with few line of code.  &lt;/p&gt;

</description>
      <category>dotvvm</category>
      <category>webforms</category>
      <category>csharp</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Build Azure Pipeline to your DotVVM application</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Mon, 25 May 2020 15:20:48 +0000</pubDate>
      <link>https://forem.com/dotvvm/build-azure-pipeline-to-your-dotvvm-application-2a0i</link>
      <guid>https://forem.com/dotvvm/build-azure-pipeline-to-your-dotvvm-application-2a0i</guid>
      <description>&lt;h4&gt;
  
  
  What is CI/CD?
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Continuous integration (CI) and continuous delivery (CD) embody a culture, set of operating principles, and collection of practices that enable application development teams to deliver code changes more frequently and reliably. The implementation is also known as the &lt;em&gt;CI/CD&lt;/em&gt; pipeline.&lt;br&gt;
src : &lt;a href="https://www.infoworld.com/article/3271126/what-is-cicd-continuous-integration-and-continuous-delivery-explained.html" rel="noopener noreferrer"&gt;https://www.infoworld.com/article/3271126/what-is-cicd-continuous-integration-and-continuous-delivery-explained.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Azure Pipeline for DevOps
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure Pipelines is a continuous delivery tool, designed to build code in popular languages, test them, and then deliver them to your choice of endpoint. Like other CI/CD systems, it’s also extensible, with a library of tasks and extensions to add support for test tool and for integration with your devops tool chain.&lt;br&gt;
src : &lt;a href="https://www.infoworld.com/article/3305845/how-to-work-with-azure-pipelines-for-devops.html" rel="noopener noreferrer"&gt;https://www.infoworld.com/article/3305845/how-to-work-with-azure-pipelines-for-devops.html&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  DotVVM CI/CD Pipeline
&lt;/h4&gt;

&lt;p&gt;In this article we will go through steps required to enable CI/CD to your DotVVM web application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To keep it short and focus on CI/CD pipeline we will not show steps required to create DevOps project on Azure DevOps. If you want to know more you can try &lt;a href="https://www.azuredevopslabs.com/labs/vstsextend/azuredevopsprojectdotnet/" rel="noopener noreferrer"&gt;this Lab&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;a href="//devops.azure.com"&gt;devops.azure.com&lt;/a&gt; and login.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your devops project and go to Pipelines then click on &lt;strong&gt;&lt;em&gt;Create Pipeline&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select where to connect to get your code. Here I host my DotVVM application on Azrue Repos Git.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AoZnSrM3Drc1fjgZyi5LXAw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AoZnSrM3Drc1fjgZyi5LXAw.png" alt="enter image description here"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure displays all available repositories in selected host. Select your DotVVM repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;once you select your target repository, Azure pipeline will go to configure your pipeline step where you select your application type. If the target application type is not listed click in &lt;strong&gt;&lt;em&gt;show more&lt;/em&gt;&lt;/strong&gt; button. &lt;br&gt;
For your DotVVM application you can select &lt;strong&gt;ASP.NET Core (.Net Framework)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2AKbjEPI85LpqOGmDjJnN7kQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2AKbjEPI85LpqOGmDjJnN7kQ.png" alt="enter image description here"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In review step, Azure displays your pipeline in YAML format. You can edit if you want manually or click on show assistant in upper right corner to select the tasks you want to to add to your pipeline.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2Aj9XlTjknawneCzqJn99r7A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2Aj9XlTjknawneCzqJn99r7A.png" alt="enter image description here"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From task list, select .Net Core task to publish your DotVVM web application.&lt;br&gt;
      - Command : publish&lt;br&gt;
      - Publish web project : checked&lt;br&gt;
      - Zip published projects : checked&lt;br&gt;
      - Add project's folder name to publish path : checked&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2Afl-lGM45iVgAL3KneiyBvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2Afl-lGM45iVgAL3KneiyBvg.png" alt="enter image description here"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From Task list select Azure App Service Deploy task to deploy your DotVVM to azure app service with the following configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connection Type : Azure Resource Manager&lt;/li&gt;
&lt;li&gt;Azure subscription : select one from your available subscriptions&lt;/li&gt;
&lt;li&gt;App Service type : Web App on Windows&lt;/li&gt;
&lt;li&gt;App Service name : select your target App service from App services available in selected subscription. If the list is empty you have to create App service first before creating your pipeline.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2A_hGN2hrmQApJIytMpc3XoA.png" alt="enter image description here"&gt;
Then click Add button to add this task to your pipeline.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Save and run to save your pipeline for future updates and run it immediately. If you don't want to run it, just click on down arrow and click save.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2AZR9qTG3P3I_fDeq6nJAxtQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2AZR9qTG3P3I_fDeq6nJAxtQ.png" alt="enter image description here"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure will commit this pipeline to your master branch or you can create a separate branch for this commit. &lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2Ao5Ti6GPp10DrgW-qduSY1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1800%2F1%2Ao5Ti6GPp10DrgW-qduSY1A.png" alt="enter image description here"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now your pipeline is configured and ready to run and deploy your DotVVM application to target Azure App service. After each push you do to master branch of your repository your azure pipeline will be triggered and deploy a new version of your DotVVM application .&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In this article we showed a simple way to configure an Azure Pipeline to enable CI/CD for your DotVVM application to be deployed to a specified Azure App Service.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>azure</category>
      <category>dotvvm</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>DotVVM:Build Conditional Validation Attribute</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Sun, 26 Apr 2020 01:32:28 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-build-conditional-validation-attribute-58c8</link>
      <guid>https://forem.com/dotvvm/dotvvm-build-conditional-validation-attribute-58c8</guid>
      <description>&lt;h4&gt;
  
  
  Validation in DotVVM
&lt;/h4&gt;

&lt;p&gt;Validation in DotVVM is very similar to validation in ASP.Net MVC and ASP.Net Core.&lt;br&gt;
You can validate your view model by using validation attributes. DotVVM do client side validation for only the following attributes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required&lt;/li&gt;
&lt;li&gt;Compare&lt;/li&gt;
&lt;li&gt;EmailAddress&lt;/li&gt;
&lt;li&gt;Range&lt;/li&gt;
&lt;li&gt;RegularExporession&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the user input is not valid you have two controls you can use to show error messages&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Validator&lt;/em&gt; Control : shows error message against the target input control&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;VaicationSummary&lt;/em&gt; Control: shows the summary for all errors in your view model. &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Straight Validation
&lt;/h4&gt;

&lt;p&gt;Suppose we have a small registaration form that requires the user to enter his/her name, gender, and age. All fields are required. To validate user's input we just need to annotate our viewmodel properties with &lt;em&gt;Required&lt;/em&gt; attribute. Our ViewModel class will be like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }

public string Gender { get; set; }

[Required(ErrorMessage = "Age is required")]
public int? Age { get; set; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In our view we will use only &lt;em&gt;Validator&lt;/em&gt; control to show error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:Literal class="control-label col-md-3" Text="Name"&amp;gt;&amp;lt;/dot:Literal&amp;gt;
&amp;lt;dot:TextBox Text="{value: Name}" class="form-control" Type="Normal"&amp;gt;&amp;lt;/dot:TextBox&amp;gt;
&amp;lt;dot:Validator HideWhenValid="true" Value="{value: Name}" ShowErrorMessageText="true"&amp;gt;&amp;lt;/dot:Validator&amp;gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;dot:Literal class="control-label col-md-3" Text="Gender"&amp;gt;&amp;lt;/dot:Literal&amp;gt;
&amp;lt;dot:RadioButton CheckedItem="{value: Gender}" CheckedValue="{value: "1"}" Text="Male"&amp;gt;&amp;lt;/dot:RadioButton&amp;gt;
&amp;lt;dot:RadioButton CheckedItem="{value: Gender}" CheckedValue="{value: "2"}" Text="Female"&amp;gt;&amp;lt;/dot:RadioButton&amp;gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;dot:Literal class="control-label col-md-3" Text="Age"&amp;gt;&amp;lt;/dot:Literal&amp;gt;
&amp;lt;dot:TextBox Text="{value: Age}" class="form-control" Type="Number"&amp;gt;&amp;lt;/dot:TextBox&amp;gt;
&amp;lt;dot:Validator HideWhenValid="true" Value="{value: Age}" ShowErrorMessageText="true"&amp;gt;&amp;lt;/dot:Validator&amp;gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;dot:Button Click="{command: Save()}" Text="Save" class="btn btn-outline-secondary btn-sm"&amp;gt;&amp;lt;/dot:Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Foucs on &lt;em&gt;validator&lt;/em&gt; control we set &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;HideWhenValid&lt;/em&gt; to &lt;em&gt;true&lt;/em&gt; to show error message &lt;strong&gt;only&lt;/strong&gt; if the user's input is not valid&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;ShowErrorMessageText&lt;/em&gt; to true to show error message that comes from our ViewModel &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Conditional Validation
&lt;/h4&gt;

&lt;p&gt;We know women don't like to tell their real age so we want to respect this in our registeration form by validating the age feild only if the user selected male as  his gender but if gender was female will not force her to enter her age.&lt;/p&gt;

&lt;p&gt;In DotVVM there is no conditional Required validation, so we need to build our custom validation attribute.&lt;br&gt;
What we actually need is just a new class that inherts &lt;em&gt;ValidationAttribute&lt;/em&gt; class and override &lt;em&gt;IsValid&lt;/em&gt; method with our  logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class RequiredIfAttribute : ValidationAttribute
{
    public string PropertyName { get; set; }
    public object Value { get; set; }

    public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
    {
        PropertyName = propertyName;
        ErrorMessage = errorMessage;
        Value = value;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var instance = validationContext.ObjectInstance;
        var type = instance.GetType();
        var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
        if (proprtyvalue.ToString() == Value.ToString() &amp;amp;&amp;amp; value == null)
        {
            return new ValidationResult(ErrorMessage);
        }
        return ValidationResult.Success;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First we added a &lt;em&gt;PropertyName&lt;/em&gt; property to check its value to start validation of skip it and &lt;em&gt;Value&lt;/em&gt; property that will check against it.&lt;br&gt;
Inside &lt;em&gt;IsValid()&lt;/em&gt; method we are using reflection to get that value of the property and check if its value is equal to the provided value in the attribute  and the value of the current field is null then the field value is not valid otherwise the field is not required.&lt;/p&gt;

&lt;p&gt;In our &lt;em&gt;ViewModel&lt;/em&gt; we will replace &lt;em&gt;Required&lt;/em&gt; attribute that decorate &lt;em&gt;Age&lt;/em&gt; property with our new custom attribute &lt;em&gt;RequiredIf&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [RequiredIf(nameof(Gender), "1", ErrorMessage = "Age is required")]
 public int? Age { get; set; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Frist parameter is the &lt;em&gt;PropertyName&lt;/em&gt; and second paramter is the &lt;em&gt;Value&lt;/em&gt; of the &lt;em&gt;Gender&lt;/em&gt; that makes &lt;em&gt;Age&lt;/em&gt; field is required (I used 1 and 2 for simpilcity).&lt;/p&gt;

&lt;h4&gt;
  
  
  Restriction
&lt;/h4&gt;

&lt;p&gt;Our custom validation is server side validation. DotVVM need you to submit your form to be able to run your custom validation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In this post we validated our ViewModel like we used to do in  ASP.Net MVC or ASP.Net Core and also created our custom validation to validate fields based on another field value.&lt;br&gt;
You can find the full source code on &lt;a href="https://github.com/miroprocessor/dotvvm-requiredIf"&gt;github&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotvvm</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Build Single Page Application with DotVVM</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Thu, 23 Apr 2020 02:22:30 +0000</pubDate>
      <link>https://forem.com/dotvvm/build-single-page-application-with-dotvvm-3kdf</link>
      <guid>https://forem.com/dotvvm/build-single-page-application-with-dotvvm-3kdf</guid>
      <description>&lt;h4&gt;
  
  
  Single Page Application (SPA)
&lt;/h4&gt;

&lt;p&gt;In an SPA your web application is divided into components(pages) and each component has its own route(URL). You can navigate between pages using normal links as you used to do in traditional web pages.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In an SPA, the entire application runs as a single web page. In this&lt;br&gt;
approach, the presentation layer for the entire application has been&lt;br&gt;
factored out of the server and is managed from within the browser.&lt;br&gt;
&lt;a href="https://livebook.manning.com/book/spa-design-and-architecture/chapter-1/13"&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  SPA with DotVVM
&lt;/h4&gt;

&lt;p&gt;To build SPA you have to learn one of JavaScript frameworks/libraries like Angular, React, or Vue.js but with DotVVM you don't need to learn any of them. DotVVM is supporting SPA by just changing main &lt;code&gt;ContentPlaceHolder&lt;/code&gt; in your DotVVM master page with &lt;code&gt;SPAContentPlaceHolder&lt;/code&gt; and use &lt;code&gt;RouteLink&lt;/code&gt;&lt;em&gt;(recommended)&lt;/em&gt; control for navigation between your DotVVM pages.&lt;/p&gt;

&lt;p&gt;DotVVM load the content pages asynchronously and &lt;code&gt;History API&lt;/code&gt; for navigation.&lt;/p&gt;

&lt;p&gt;lets try it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create new DotVVM web application with sample CRUD pages.&lt;/li&gt;
&lt;li&gt;Build and run your application and try to navigate between different pages.

&lt;ul&gt;
&lt;li&gt;You will notice your browser is loading each page.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Open Views/MasterPage.dotmaster file and find
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:ContentPlaceHolder ID="MainContent" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and replace it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:SpaContentPlaceHolder ID="MainContent" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Refresh your page using CTRL+F5&lt;/li&gt;
&lt;li&gt;Navigate between your pages again you can notice that your browser is rendering pages without any loading.&lt;/li&gt;
&lt;li&gt;View your page source in your browser you will notice that any &lt;code&gt;RouteLink&lt;/code&gt; control is rendered with  &lt;code&gt;dotvvm.handleSpaNavigation(this);&lt;/code&gt; is added to its &lt;code&gt;onclick&lt;/code&gt; event. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Restriction
&lt;/h4&gt;

&lt;p&gt;You can &lt;strong&gt;NOT&lt;/strong&gt; use multiple &lt;code&gt;SpaContentPlaceHolder&lt;/code&gt; controls in your DotVVM master page.&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In this article we demonstrated how it is pretty easy to build SPA with DotVVM without learning a new framework or library.&lt;/p&gt;

</description>
      <category>dotvvm</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>spa</category>
    </item>
    <item>
      <title>DotVVM : Add shortcuts to your buttons and links</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Wed, 15 Apr 2020 01:27:23 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-add-shortcuts-to-your-buttons-and-links-12ep</link>
      <guid>https://forem.com/dotvvm/dotvvm-add-shortcuts-to-your-buttons-and-links-12ep</guid>
      <description>&lt;p&gt;As developers we used to use shortcuts during writing code. The most famous shortcut for developer and non-developer is  &lt;em&gt;CTRL+S&lt;/em&gt;  for save command,  &lt;em&gt;CTRL+C&lt;/em&gt;  for copy command and  &lt;em&gt;CTRL+V&lt;/em&gt;  for paste command.&lt;/p&gt;

&lt;p&gt;If you would like to add command shortcuts to your web application you need to write a massive JavaScript code but with  &lt;a href="https://www.dotvvm.com/"&gt;DotVVM&lt;/a&gt;  it is just a matter of one line in your markup file.&lt;/p&gt;

&lt;p&gt;One of available controls in DotVVM  &lt;strong&gt;Business Pack&lt;/strong&gt;  is  &lt;em&gt;CommandShortcut&lt;/em&gt;  control which is allowing you to assign shortcut keys to commands in your web application. Lets see how we can achieve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  CommandShortcut Control
&lt;/h2&gt;

&lt;p&gt;it is an invisible DotVVM control lives in  &lt;strong&gt;&lt;em&gt;DotVVM.BusinessPack.Controls&lt;/em&gt;&lt;/strong&gt;  namespace and allows to triggers a command a viewmodel for a key shortcut.&lt;/p&gt;

&lt;p&gt;You can create different combinations of shortcut using  &lt;em&gt;CTRL&lt;/em&gt;,  &lt;em&gt;Shift&lt;/em&gt;,  &lt;em&gt;Alt&lt;/em&gt;, and  &lt;em&gt;Key&lt;/em&gt;  properties of  &lt;em&gt;CommandShortcut&lt;/em&gt;  control.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open your Visual Studio and create new DotVVM Web Application.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Custom Your DotVVM Project, check DotVVM Business Pack and Sample CRUD Page checkboxes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5nssVgwz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3675/1%2AHvMkJ0dV1fcVd4HEYrd_3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5nssVgwz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3675/1%2AHvMkJ0dV1fcVd4HEYrd_3w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note : You must have a valid license to be able to check DotVVM Business Pack checkbox otherwise it will be disabled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open &lt;em&gt;DotVVMStartup.cs&lt;/em&gt; and add the below line to &lt;em&gt;ConfigureServices()&lt;/em&gt;  method if doesn’t exist.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;options.AddBusinessPack();
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build and run your application. In the Home page you will New Item button that we want to create a shortcut key for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rrWhVazP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/4363/1%2Amo3bbdxlFSvqcAprtcTcag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rrWhVazP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/4363/1%2Amo3bbdxlFSvqcAprtcTcag.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;Default.dothtml&lt;/em&gt;  file you and add the below lines where we add  &lt;em&gt;CommandShortcut&lt;/em&gt;  control and create a new shortcut using  &lt;strong&gt;&lt;em&gt;CTRL+ALT+N&lt;/em&gt;&lt;/strong&gt;  combination.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;bp:CommandShortcut Ctrl="true"   
                Shift="false"  
                Alt="true"  
                Key="N"  
                Command="{command: NewItem()}" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;ViewModels/DefaultViewModel.cs&lt;/em&gt;  file and add  &lt;em&gt;NewItem()&lt;/em&gt;  method that just do nothing but redirects to the  &lt;em&gt;CRUD_Create&lt;/em&gt;  route&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void NewItem()  
{  
Context.RedirectToRoute("CRUD_Create");  
}
&lt;/code&gt;&lt;/pre&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: Here we added a new method just for redirecting to&lt;/em&gt; CRUD_Create &lt;em&gt;route because&lt;/em&gt; RouteLink &lt;em&gt;doesn’t have command property. another work around is replace&lt;/em&gt; RouteLink &lt;em&gt;control with&lt;/em&gt; Button &lt;em&gt;control.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build and run your solution&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;press  &lt;strong&gt;CTRL+ALT+N&lt;/strong&gt;  to redirect to create view.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this article we knew how to create a shortcut key to command using  &lt;em&gt;CommandShortcut&lt;/em&gt;  control which is part of  &lt;strong&gt;DotVVM Business Pack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can find the full code on  &lt;a href="https://github.com/miroprocessor/dotvvm-shortcuts"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>dotvvm</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>html</category>
    </item>
    <item>
      <title>DotVVM: upload files using FileUpload control</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Tue, 07 Apr 2020 15:09:43 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-upload-files-using-fileupload-control-4b85</link>
      <guid>https://forem.com/dotvvm/dotvvm-upload-files-using-fileupload-control-4b85</guid>
      <description>&lt;p&gt;In this post I will show you how it is so easy in &lt;a href="https://www.dotvvm.com/"&gt;DotVVM&lt;/a&gt; to upload files to a local folder or even to a blob container in your Azure Storage Account using &lt;a href="https://www.dotvvm.com/docs/controls/builtin/FileUpload/latest"&gt;FileUpload&lt;/a&gt; control.&lt;/p&gt;

&lt;h4&gt;
  
  
  Uploading files to Local storage.
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create Empty DotVVM web project in visual studio.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ORy8cJRX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q6t3nlr909kafzgx6of8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ORy8cJRX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q6t3nlr909kafzgx6of8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open &lt;em&gt;DotvvmStartup.cs&lt;/em&gt; file and add the following line to &lt;em&gt;ConfigureServices&lt;/em&gt; methods if not exist.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;options.AddDefaultTempStorages("temp");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line is telling DotVVM to set the the default temporary storage to &lt;em&gt;temp&lt;/em&gt; folder. Once you try to upload any file DotVVM will create that folder in the root directory of your application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open &lt;em&gt;ViewModels/DefaultViewModel&lt;/em&gt; file and replace its content with the following code.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using DotVVM.Framework.Controls;
....
namespace DotVVMUploader.ViewModels
{
public class DefaultViewModel : MasterPageViewModel
{
    public string Title { get; set; }
    public UploadedFilesCollection FilesCollection { get; set; }
    public DefaultViewModel()
    {
        Title = "Welcome to upload files sample";
        FilesCollection = new UploadedFilesCollection();
    }
}
}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;We defined &lt;em&gt;FilesCollection&lt;/em&gt; property as &lt;em&gt;UploadedFilesCollection&lt;/em&gt;. This property will contain our uploaded files.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open &lt;em&gt;Views/Default.dothtml&lt;/em&gt; file and add the following code.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:FileUpload UploadedFiles="{value: FilesCollection}"
            AllowMultipleFiles="true"
            AllowedFileTypes=".png,.jpg"
            SuccessMessageText="Uploaded"
            UploadButtonText="Select Files to Upload"&amp;gt;&amp;lt;/dot:FileUpload&amp;gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Here, we are adding &lt;em&gt;FileUpload&lt;/em&gt; control and set its properties as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;UploadFiles&lt;/em&gt; : set to &lt;em&gt;FilesCollection&lt;/em&gt; collection we have defined in the ViewModel class. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;AllowMultipleFiles&lt;/em&gt; : set to true to be able to upload many files at once.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;AllowedFileTypes&lt;/em&gt; : set to restrict the file types you allow user to upload.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;SuccessMessageText&lt;/em&gt; : the message you want to display in the page to inform the user that the upload is finished with no error.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;UploadButtonText&lt;/em&gt; : the text you want to display as a text for upload button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;By default DotVVM will save your file with &lt;em&gt;.tmp&lt;/em&gt; extension and keep it for 30 minutes then will be deleted automatically.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To save your files to a permanent location/storage you need to do that by yourself.&lt;br&gt;
In the &lt;em&gt;FileUpload&lt;/em&gt; control markup will set &lt;em&gt;UploadCompleted&lt;/em&gt; attribute with the name of the event that will be triggered once the upload is completed.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:FileUpload UploadedFiles="{value: FilesCollection}"
                AllowMultipleFiles="true"
                AllowedFileTypes=".png,.jpg"
                SuccessMessageText="Uploaded"
                UploadButtonText="Select Files to Upload"
                UploadCompleted="{command: SaveMyFilesLocally()}"&amp;gt;&amp;lt;/dot:FileUpload&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need to inject &lt;em&gt;IUploadedFileStorage&lt;/em&gt; to &lt;em&gt;DefaultViewModel&lt;/em&gt; class.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private readonly IUploadedFileStorage _uploadedFileStorage;
...
public DefaultViewModel(IUploadedFileStorage uploadedFileStorage)
{
  _uploadedFileStorage = uploadedFileStorage;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And here &lt;em&gt;SaveMyFilesLocally()&lt;/em&gt; method that we added in &lt;em&gt;FileUpload&lt;/em&gt; markup.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void SaveMyFilesLocally()
{
if (!FilesCollection.IsBusy)
{
  var permenentPath = Path.Combine(Context.Configuration.ApplicationPhysicalPath, "ProcessedFiles");
  if (!Directory.Exists(permenentPath))
  {
      Directory.CreateDirectory(permenentPath);
  }
  foreach (var file in FilesCollection.Files)
  {
       var newFileName = $"{Path.GetFileNameWithoutExtension(file.FileName)}_{file.FileId}{Path.GetExtension(file.FileName)}";
        var filePath = Path.Combine(permenentPath, newFileName);
        _uploadedFileStorage.SaveAs(file.FileId, filePath);
        _uploadedFileStorage.DeleteFile(file.FileId);
   }
   FilesCollection.Clear();
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;First we check if &lt;em&gt;FilesCollection&lt;/em&gt; is busy with uploading files. If not, we start to process our uploaded files by looping over &lt;em&gt;Files&lt;/em&gt; property of our &lt;em&gt;FilesCollection&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;After saving our file to permanent storage we delete it from the temp folder. Deleting files from temp folder is not necessary as DotVVM will delete it after 30 minutes but it is good to do to specially if your application upload huge number of files.&lt;/li&gt;
&lt;li&gt;Then we clear our &lt;em&gt;FilesCollection&lt;/em&gt; to not process the same files again if we uploaded another set of files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is how our sample page looks like&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--La4RlKy9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9qmoeyk5yu18jfkcimmq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--La4RlKy9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9qmoeyk5yu18jfkcimmq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Uploading files to Azure Storage Account.
&lt;/h4&gt;

&lt;p&gt;Here is the magic of DotVVM begins. If any point of time you decided to upload your file to the Azure Storage Account instead of local storage, what all you need is modify &lt;em&gt;SaveMyFilesLocally&lt;/em&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For demonstration purpose we will add a new method &lt;em&gt;SaveMyFilesToAzure&lt;/em&gt; and let &lt;em&gt;FileUpload&lt;/em&gt; point to it.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dot:FileUpload UploadedFiles="{value: FilesCollection}"
                    AllowMultipleFiles="true"
                    AllowedFileTypes=".png,.jpg"
                    SuccessMessageText="Uploaded"
                    UploadButtonText="Select Files to Upload"
                    UploadCompleted="{command: SaveMyFilesToAzure()}"&amp;gt;&amp;lt;/dot:FileUpload&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;em&gt;WindowsAzure.Storage&lt;/em&gt; nuget package&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install-Package WindowsAzure.Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following using statement to &lt;em&gt;DefaultViewModel&lt;/em&gt; class.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.WindowsAzure.Storage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add &lt;em&gt;SaveMyFilesToAzure&lt;/em&gt; method to &lt;em&gt;DefaultViewModel&lt;/em&gt; class&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task SaveMyFilesToAzure()
{
if (!FilesCollection.IsBusy)
{
    var stoageAccount = CloudStorageAccount.DevelopmentStorageAccount;
    var blobStorageClient = stoageAccount.CreateCloudBlobClient();
    var container = blobStorageClient.GetContainerReference("dotvvmblobcontainer");
    await container.CreateIfNotExistsAsync();
    foreach (var file in FilesCollection.Files)
    {
        var newFileName = $"{Path.GetFileNameWithoutExtension(file.FileName)}_{file.FileId}{Path.GetExtension(file.FileName)}";
        var blobRef = container.GetBlockBlobReference(newFileName);
        await blobRef.UploadFromFileAsync($"temp/uploadedFiles/{file.FileId}.tmp");
    }
    FilesCollection.Clear();
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you see it is almost the same as before. We just creating a client to Azure Storage Account. &lt;br&gt;
&lt;strong&gt;Here I'm using the Storage Account Emulator. Explaining how to use it is out of the scope of this article. You can refer to &lt;a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-use-emulator"&gt;Microsoft Documentations&lt;/a&gt; for more details.&lt;/strong&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In this post we demonstrated how it is pretty easy to upload files with DotVVM FileUpload Control to your local storage and to your Azure Blob Container.&lt;/p&gt;

&lt;p&gt;You can find the full code on &lt;a href="https://github.com/miroprocessor/dotvvm-uploadfiles"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotvvm</category>
      <category>azure</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>DotVVM Authorization with IdentityServer4</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Sat, 21 Mar 2020 15:53:34 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-authorization-with-identityserver4-3jn4</link>
      <guid>https://forem.com/dotvvm/dotvvm-authorization-with-identityserver4-3jn4</guid>
      <description>&lt;p&gt;DotVVM is open source MVVM framework for ASP.Net Core and OWIN and it is member of &lt;a href="https://dotnetfoundation.org/"&gt;.Net Foundation&lt;/a&gt;. DotVVM is a free to use under Apache License but also have commercial extensions.&lt;/p&gt;

&lt;p&gt;DotVVM lets you build interactive web UIs with just C# and HTML using MVVM pattern. DotVVM framework is shipped with many build-in controls like &lt;em&gt;GridView&lt;/em&gt;, &lt;em&gt;FileUpload&lt;/em&gt;, &lt;em&gt;Validators&lt;/em&gt;, and more.&lt;/p&gt;

&lt;p&gt;To learn more about DotVVM framework visit &lt;a href="https://www.dotvvm.com/"&gt;DotVVM.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this article we will see how to secure your DotVVM web application using IdentityServer4.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is IdentityServer4?
&lt;/h4&gt;

&lt;p&gt;IdentityServer4 is an OpenID Connect and OAuth2.0 framework for ASP.Net Core. it enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Authentication as a service&lt;/li&gt;
&lt;li&gt;  Single Sign-n (SSO)&lt;/li&gt;
&lt;li&gt;  Access control for APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and more.&lt;/p&gt;

&lt;p&gt;It is an open source framework you get its code from &lt;a href="https://github.com/IdentityServer/IdentityServer4"&gt;GitHub repository&lt;/a&gt; and the &lt;a href="https://identityserver4.readthedocs.io/en/latest/"&gt;full documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;You can check my  &lt;a href="https://dev.to/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah"&gt;previous article&lt;/a&gt;  to know how to install DotVVM extension.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First of all we need to prepare our IdentityServer4 as our authentication service. IdentityServer4 has different templates to use, for simplicity we will use out of the box IdentityServer4 UI template which provides a complete UI for defining roles, users, clients, claim types,.etc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To install IdentityServer templates for dotnet CLI run this command in console window.&lt;br&gt;
&lt;code&gt;dotnet new -i IdentityServer4.Templates&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From cmd or windows PowerShell run following commands&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;md dotvvm/src //create folder for our solution
cd dotvvm/src
dotnet new sln -n dotvvm
dotnet new is4admin -n dotvvm.auth
dotnet sln add .\dotvvm.auth\dotvvm.auth.csproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your solution in vs2019 or vs code, your solution should look like&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-SmKRZziPs78/XnFDSaXVX6I/AAAAAAAACmg/9wJ_GjwslcsO-4mQAeFhSW9EFl3O52GggCLcBGAsYHQ/s1600/solution-explorer.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4YJvJO7G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-SmKRZziPs78/XnFDSaXVX6I/AAAAAAAACmg/9wJ_GjwslcsO-4mQAeFhSW9EFl3O52GggCLcBGAsYHQ/s200/solution-explorer.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;build and run you solution it should see a page like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-W2I28RWc_3I/XnFEFa1D71I/AAAAAAAACms/rPoj8Bj4FqMNAWcotvet6Rsmmza_Q7c6QCLcBGAsYHQ/s1600/is4-admin-ui.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n2RLPvhH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-W2I28RWc_3I/XnFEFa1D71I/AAAAAAAACms/rPoj8Bj4FqMNAWcotvet6Rsmmza_Q7c6QCLcBGAsYHQ/s400/is4-admin-ui.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To add your users, roles, and clients, click on highlighted link then click on start&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-caYVyzMDyq8/XnFE-XNNTOI/AAAAAAAACm8/Lhe-ajWdhQUDzbst9aQBQvgk2br5Mcm1wCLcBGAsYHQ/s1600/admin-start.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_peeFyDJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-caYVyzMDyq8/XnFE-XNNTOI/AAAAAAAACm8/Lhe-ajWdhQUDzbst9aQBQvgk2br5Mcm1wCLcBGAsYHQ/s200/admin-start.png" alt=""&gt;&lt;/a&gt;&lt;a href="https://1.bp.blogspot.com/-RjuueYyMiQo/XnFFYvXhCaI/AAAAAAAACnE/3GxE86LKhfU9yWLa8I5JGa9Z_EyJodj1wCEwYBhgL/s1600/admin-controls.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZdl2rsj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-RjuueYyMiQo/XnFFYvXhCaI/AAAAAAAACnE/3GxE86LKhfU9yWLa8I5JGa9Z_EyJodj1wCEwYBhgL/s200/admin-controls.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
Open Users page and click on Add User button then fill the New User form where you define your user and his login credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note : Save user name and password as you will use it when you run your DotVVM application.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-AE97Bf7buCE/XnFHTd3J3RI/AAAAAAAACnQ/nhUylRL4PHUNkGCaE0T3MG__1zkOVuxdgCLcBGAsYHQ/s1600/admin-new-user.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DtknSaLG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-AE97Bf7buCE/XnFHTd3J3RI/AAAAAAAACnQ/nhUylRL4PHUNkGCaE0T3MG__1zkOVuxdgCLcBGAsYHQ/s200/admin-new-user.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Define your application as Client
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt; Open Clients page and click on Add Client button&lt;/li&gt;
&lt;li&gt; Select Web App then click Start&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill your application main details then click Next.&lt;br&gt;
Client ID : dotvvm-article-sample.&lt;br&gt;
DotVVM Framework&lt;br&gt;
&lt;a href="https://localhost:5001"&gt;https://localhost:5001&lt;/a&gt;&lt;br&gt;
&lt;a href="https://1.bp.blogspot.com/-l8tzzPoLHuU/XnFK_m5ek8I/AAAAAAAACnk/JWHh6qlAHBQip7Ljk8-VAUZmTmPp167ngCLcBGAsYHQ/s1600/admin-new-client-1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--51beY-K1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-l8tzzPoLHuU/XnFK_m5ek8I/AAAAAAAACnk/JWHh6qlAHBQip7Ljk8-VAUZmTmPp167ngCLcBGAsYHQ/s320/admin-new-client-1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Callback URL. It is a URL to a page in your DotVVM application where IdentityServer will redirect to it if sign-in is succeeded. Enter &lt;a href="https://localhost:5001"&gt;https://localhost:5001&lt;/a&gt; then click next.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post-logout URL: leave it empty and click next&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Secret: in this screen you specify a secret key for your DotVVM application. That key will be used in DotVVM application to identify your requests to IdentityServer. enter these values and click Add then click Next.&lt;/p&gt;

&lt;p&gt;Type: Shared Secret&lt;br&gt;
Value: dotvvm-secret&lt;br&gt;
Expiration Date: 03/18/2025&lt;br&gt;
&lt;a href="https://1.bp.blogspot.com/-qxpN1xyrvKU/XnP-szblwSI/AAAAAAAACn4/JRiVFu37MDsFGiewppBTH0jDlGQzv55fwCLcBGAsYHQ/s1600/admin-new-client-secret.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BV_ZXJmE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-qxpN1xyrvKU/XnP-szblwSI/AAAAAAAACn4/JRiVFu37MDsFGiewppBTH0jDlGQzv55fwCLcBGAsYHQ/s320/admin-new-client-secret.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Identity Resource: select all available resource that can be accessible by your DotVVM application then click Next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-R2NqhZgNzeE/XnQA-e-XrKI/AAAAAAAACoI/j-rKe1NZGdkKlz4VP9ll3zJ9PLHrmoAawCLcBGAsYHQ/s1600/admin-new-client-identity-resources.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xHLIoHrR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-R2NqhZgNzeE/XnQA-e-XrKI/AAAAAAAACoI/j-rKe1NZGdkKlz4VP9ll3zJ9PLHrmoAawCLcBGAsYHQ/s320/admin-new-client-identity-resources.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Protected Resources:select all available resources that can be accessible by your DotVVM application then click Next.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review your choices and click Save&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your client details and go to Advanced -&amp;gt; Token tab and check Always Include UserClaims In Id Token&lt;br&gt;&lt;br&gt;
&lt;a href="https://1.bp.blogspot.com/-zrWD1XKoT4Y/XnXZrAGlqMI/AAAAAAAACpY/S9WeTjlh76MnpIkxcqRD87GAFxJH66CjACLcBGAsYHQ/s1600/admin-claims.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g8hSpyie--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-zrWD1XKoT4Y/XnXZrAGlqMI/AAAAAAAACpY/S9WeTjlh76MnpIkxcqRD87GAFxJH66CjACLcBGAsYHQ/s320/admin-claims.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Differences between different options we have selected is out of scope of this post.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  DotVVM Application
&lt;/h4&gt;

&lt;p&gt;We will create a new empty DotVVM application, just include Bootstrap and Authentication sample code.&lt;/p&gt;

&lt;p&gt;You can check this &lt;a href="https://dev.to/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah"&gt;post&lt;/a&gt;  for full steps of DotVVM application creation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-t1iK2SvMyQw/XnQFhcfXMNI/AAAAAAAACok/rvt8RCNDjHcMLzFw15js9uBGhYbBoH_rgCLcBGAsYHQ/s1600/new-dotvvm-project.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eESjrrG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-t1iK2SvMyQw/XnQFhcfXMNI/AAAAAAAACok/rvt8RCNDjHcMLzFw15js9uBGhYbBoH_rgCLcBGAsYHQ/s400/new-dotvvm-project.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is recommended to change you the target framework of your DotVVM application to .Net Core 3.1 and also re-install Microsoft.AspNetCore.Authentication.Cookies package.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open Program.cs file and add the following line to BuildWebHost method. We specify the URL of the DotVVM application to match what we have used while configuring the IdentityServer client.
&lt;code&gt;.UseUrls("https://localhost:5001")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Install &lt;code&gt;Microsoft.AspNetCore.Authentication.OpenIdConnect&lt;/code&gt; package.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;replace &lt;code&gt;ConfigureServices&lt;/code&gt; method with the following code&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection();
services.AddAuthorization();
services.AddWebEncoders();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =&amp;gt;{
     options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =&amp;gt;{
    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;
    options.SaveTokens = true;
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.ClientId = "dotvvm-article-sample";
    options.ClientSecret = "dotvvm-secret";
    options.ResponseType = "id_token token";
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.CallbackPath = "/signin-oidc";
 });
 services.AddRazorPages();
 services.AddDotVVM&amp;lt;DotvvmStartup&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;replace the Configure method with the following code&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  app.UseAuthentication();
  app.UseRouting();
  app.UseAuthorization();
  // use DotVVM
  var dotvvmConfiguration = app.UseDotVVM&amp;lt;DotvvmStartup&amp;gt;(env.ContentRootPath);
  dotvvmConfiguration.AssertConfigurationIsValid();
  // use static files
  app.UseStaticFiles(new StaticFileOptions
    {
       FileProvider = new PhysicalFileProvider(env.WebRootPath)
    });
   app.UseEndpoints(endpoints =&amp;gt;
   {
     endpoints.MapRazorPages();
   });
}
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open ViewModels/MasterPageViewModel.cs file and decorate MaterPageViewModel class with Authorize attribute.&lt;br&gt;&lt;br&gt;
&lt;code&gt;[Authorize]&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;public class MasterPageViewModel : DotvvmViewModelBase&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following line to MasterPageVeiwModel class to read name of the logged in user from IdentityServer claims.&lt;br&gt;&lt;br&gt;
&lt;code&gt;public string Username =&amp;gt; Context.HttpContext.User.FindFirst("name")?.Value;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open Views/Default.dothtml file and add this div to content control&lt;br&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;div class="alert alert-info"&amp;gt;Welcome to DotVVM, {{value: Username}}&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;First you must run dotvvm.auth project and once you run your dotvvm.web project it will be redirected login page of IdentityServer&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-l_6l5mdcIpI/XnQRfLuiKZI/AAAAAAAACow/I1BBBCkh2-UH-EE5FWceKDRKo5S7Ip2WwCLcBGAsYHQ/s1600/login-page.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---xOxXuQJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-l_6l5mdcIpI/XnQRfLuiKZI/AAAAAAAACow/I1BBBCkh2-UH-EE5FWceKDRKo5S7Ip2WwCLcBGAsYHQ/s320/login-page.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;After logging using username and password you have specified while creating user step, you will be redirected to permission pages where IdentityServer asking for your permission.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-WrXTX4yGcSI/XnQUYB8AFKI/AAAAAAAACo8/HGDiVnRAnLg2Q11N05UdWnEemUjnn5dlQCLcBGAsYHQ/s1600/permissions-page.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bUvnrkda--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-WrXTX4yGcSI/XnQUYB8AFKI/AAAAAAAACo8/HGDiVnRAnLg2Q11N05UdWnEemUjnn5dlQCLcBGAsYHQ/s320/permissions-page.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Check permission you want to allow then click Yes, Allow button to go to your DotVVM application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-Pl7S0vWR3gY/XnXZ-iGD9MI/AAAAAAAACpc/8v_aZR9EpFclyRHJlrNK1dacnHCNWvqYgCLcBGAsYHQ/s1600/home.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J5fDze_U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-Pl7S0vWR3gY/XnXZ-iGD9MI/AAAAAAAACpc/8v_aZR9EpFclyRHJlrNK1dacnHCNWvqYgCLcBGAsYHQ/s320/home.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In this article we showed how to use IdentityServer4 to Authenticate your DotVVM application.&lt;br&gt;
You can find the complete code sample in &lt;a href="https://github.com/miroprocessor/dotvvm-identityserver"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotvvm</category>
      <category>identityserver</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title> DotVVM CRUD application with  Entity Framework and Cosmos DB</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Thu, 05 Mar 2020 23:58:36 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah</link>
      <guid>https://forem.com/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is DotVVM?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DotVVM is open source MVVM framework for ASP.Net Core and OWIN and it is member of  &lt;a href="https://dotnetfoundation.org/" rel="noopener noreferrer"&gt;.NetFoundation&lt;/a&gt;. DotVVM is a free to use under Apache License but also have commercial extensions.&lt;/p&gt;

&lt;p&gt;DotVVM lets you build interactive web UIs with just C# and HTML using MVVM pattern. DotVVM framework is shipped with many build-in controls like  &lt;em&gt;GridView&lt;/em&gt;,  &lt;em&gt;FileUpload&lt;/em&gt;,  &lt;em&gt;Validators&lt;/em&gt;, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why DotVVM?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are many reason and business scenarios that DotVVM is suitable for and very helpful like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Migrating legacy ASP.Net web forms application to .Net Core.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New ASP.Net applications that contains many forms with a lot of controls/components.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more about DotVVM framework visit &lt;a href="https://www.dotvvm.com/" rel="noopener noreferrer"&gt;DotVVM.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Azure Cosmos DB?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure Cosmos DB is a NoSQL distributed and fully managed database service. Azure Cosmos DB provides different API for different NoSQL models like Document databases, Column databases, Graph databases and Key-Value database.&lt;/p&gt;

&lt;p&gt;You can easily migrate your existing database on your prim to Azure Cosmos DB using Cosmos migration tool.&lt;/p&gt;

&lt;p&gt;In this article we will go through a sample project to demonstrate how it is easy to use DotVVM framework in building your web application with Azure Cosmos DB as your data store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install DotVVM extension&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open Visual Studio 2019 (you can use Visual Studio 2017 as well)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open Manage Extension window&lt;/p&gt;

&lt;p&gt;Extensions &amp;gt; Manage Extensions &amp;gt; Online menu&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In search box type DotVVM and click Download&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-p9Oe7ccO5bQ/XfpJ-WwbnDI/AAAAAAAACdM/XsjPaOoOGtw1Tr4IXzljMkjiip4JD849wCLcBGAsYHQ/s1600/0-%2Binstall%2BDotVVM%2Bextension.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-p9Oe7ccO5bQ%2FXfpJ-WwbnDI%2FAAAAAAAACdM%2FXsjPaOoOGtw1Tr4IXzljMkjiip4JD849wCLcBGAsYHQ%2Fs400%2F0-%252Binstall%252BDotVVM%252Bextension.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart Visual Studio to complete DotVVM installation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should find DotVVM in Extension menu.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To know more about the DotVVM extension visit its page on visual studio marketplace:&lt;a href="https://marketplace.visualstudio.com/items?itemName=TomasHerceg.DotVVM-VSExtension2019" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=TomasHerceg.DotVVM-VSExtension2019&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you are ready to start coding with DotVVM framework. DotVVM extension installs DotVVM sample project which we will use to demonstrate how it is easy to connect to Azure Cosmos DB from DotVVM application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DotVVM Web Application&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create new project&lt;br&gt;&lt;br&gt;
In create new project window, filter project list by DotVVM and select DotVVM Web Application (.NET Core) and click next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-E6J471Z5GOU/XfpLZpA3xMI/AAAAAAAACdY/ofLkuwyrNT0W87ZlS2QO81PiHMym-bbrwCLcBGAsYHQ/s1600/1-%2Bnew%2BDotVVM%2Bproject.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-E6J471Z5GOU%2FXfpLZpA3xMI%2FAAAAAAAACdY%2FofLkuwyrNT0W87ZlS2QO81PiHMym-bbrwCLcBGAsYHQ%2Fs400%2F1-%252Bnew%252BDotVVM%252Bproject.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enter “&lt;em&gt;DotVVMCosmos&lt;/em&gt;” as project name, project path, and “&lt;em&gt;DotVVMCosmos&lt;/em&gt;” as solution name then click create&lt;br&gt;&lt;br&gt;
&lt;em&gt;Project name and solution name can be any value you want.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://2.bp.blogspot.com/-KiUkmSu85eM/XfpL6tfPCnI/AAAAAAAACdg/kAhZ-0E25T8prtClQ58H2k1UrSB5ZT5hACLcBGAsYHQ/s1600/2-%2Bproject%2Bname%2Band%2Bpath.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F2.bp.blogspot.com%2F-KiUkmSu85eM%2FXfpL6tfPCnI%2FAAAAAAAACdg%2FkAhZ-0E25T8prtClQ58H2k1UrSB5ZT5hACLcBGAsYHQ%2Fs400%2F2-%252Bproject%252Bname%252Band%252Bpath.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In “Customize Your DotVVM Project” window select&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Bootstrap 3&lt;/li&gt;
&lt;li&gt;No Authentication&lt;/li&gt;
&lt;li&gt;Sample CRUD Page&lt;/li&gt;
&lt;li&gt;.NET Core 3.0 (you can target another .NET core version)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then click Create Project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://2.bp.blogspot.com/-98WCgw_QBd8/XfpMnvPS-0I/AAAAAAAACds/rc-yPnPosZQUgF7Q_y80d92KjcGnNFnCwCLcBGAsYHQ/s1600/3-%2Bcustomize%2BDotVVM%2Bproject.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F2.bp.blogspot.com%2F-98WCgw_QBd8%2FXfpMnvPS-0I%2FAAAAAAAACds%2Frc-yPnPosZQUgF7Q_y80d92KjcGnNFnCwCLcBGAsYHQ%2Fs400%2F3-%252Bcustomize%252BDotVVM%252Bproject.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your project structure will be as shown&lt;/p&gt;

&lt;p&gt;&lt;a href="https://4.bp.blogspot.com/-OxJwZO37gwI/XfpNHFZ8VuI/AAAAAAAACd0/I-3eYC4d96oFeg0k1CyLZ6SlpIZQ9o5cgCLcBGAsYHQ/s1600/solution.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F4.bp.blogspot.com%2F-OxJwZO37gwI%2FXfpNHFZ8VuI%2FAAAAAAAACd0%2FI-3eYC4d96oFeg0k1CyLZ6SlpIZQ9o5cgCLcBGAsYHQ%2Fs400%2Fsolution.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DotVVM sample project uses Entity Framework Code First approach and provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Sample entity (Student)&lt;/li&gt;
&lt;li&gt;  DbContext class (StudentDbContext)&lt;/li&gt;
&lt;li&gt;  Two model classes (StudentDetailModel,  StudentListModel)&lt;/li&gt;
&lt;li&gt;  CRUD Service class (StudentService) : contains all methods required to do your CRUD operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create Azure Cosmos DB Account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use existing Azure subscription to create Azure Cosmos DB account. If you don’t have active azure subscription still you can try Azure Cosmos DB for free for 30 days.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Go to  &lt;a href="https://azure.microsoft.com/en-us/try/cosmosdb/" rel="noopener noreferrer"&gt;https://azure.microsoft.com/en-us/try/cosmosdb/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Sign in with your Microsoft account or GitHub account&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select SQL API  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-_PfQMUGOnrc/XfpO1rrV5qI/AAAAAAAACeA/8bF0nOuFObMIi0vBOmfo9HUQBZFxd4l0wCLcBGAsYHQ/s1600/5-%2Bselect%2BSQL%2BAPI.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-_PfQMUGOnrc%2FXfpO1rrV5qI%2FAAAAAAAACeA%2F8bF0nOuFObMIi0vBOmfo9HUQBZFxd4l0wCLcBGAsYHQ%2Fs320%2F5-%252Bselect%252BSQL%252BAPI.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Microsoft will create Azure Cosmos DB Account for you and the overview page will look like  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://3.bp.blogspot.com/-9cWD3F9tpnQ/XfpRijmEDpI/AAAAAAAACeQ/pCWM5fkEBqkiCA9GqcAeS0qGq2VlrSgnQCLcBGAsYHQ/s1600/cosmos%2Baccount.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-9cWD3F9tpnQ%2FXfpRijmEDpI%2FAAAAAAAACeQ%2FpCWM5fkEBqkiCA9GqcAeS0qGq2VlrSgnQCLcBGAsYHQ%2Fs400%2Fcosmos%252Baccount.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In left side menu click on Keys. From read-write keys tab, copy URI and Primary Key values and keep it.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://3.bp.blogspot.com/-NdTx8M6vbAM/XfpSFEcmgmI/AAAAAAAACec/twDx-MFzi54MHJostUZv1mvp7dtecppegCLcBGAsYHQ/s1600/keys.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-NdTx8M6vbAM%2FXfpSFEcmgmI%2FAAAAAAAACec%2FtwDx-MFzi54MHJostUZv1mvp7dtecppegCLcBGAsYHQ%2Fs400%2Fkeys.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Back to our DotVVM project to make the required modification to connect to Azure Cosmos DB.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Uninstall entity framework Sql Server related nuget package
&lt;code&gt;Microsoft.EntityFrameworkCore.SqlServer&lt;/code&gt; and &lt;code&gt;Microsoft.EntityFrameworkCore&lt;/code&gt;
As we will connect to Azure Cosmos DB not Sql Server database&lt;/li&gt;
&lt;li&gt;  Install  &lt;code&gt;Microsoft.EntityFrameworkCore.Cosmos&lt;/code&gt; nuget package&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;appsettings.json&lt;/em&gt;  file and replace its content with the following&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "AppSettings": {&lt;br&gt;
    "EndPoint": "&amp;lt;your cosmos db uri&amp;gt;",&lt;br&gt;
    "Cosmoskey": "&amp;lt;your cosmos db primary key&amp;gt;",&lt;br&gt;
    "DatabaseName": "DotVVM-Cosmos"&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Appsetting.json file contains the default connection string for Local DB but we will connect to Azure Cosmos DB so no need to keep default connection string in our code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;Startup.cs&lt;/em&gt;  file and replace  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;services.AddEntityFrameworkSqlServer()&lt;br&gt;
                .AddDbContext(options =&amp;gt;&lt;br&gt;
                {                        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));&lt;br&gt;
                });&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;with&lt;/p&gt;

&lt;p&gt;&lt;code&gt;services.AddEntityFrameworkCosmos()&lt;br&gt;
                .AddDbContext(options =&amp;gt;&lt;br&gt;
                {                        options.UseCosmos(Configuration.GetSection("AppSettings").GetValue("EndPoint"),                            Configuration.GetSection("AppSettings").GetValue("Cosmoskey"),databaseName: Configuration.GetSection("AppSettings").GetValue("DatabaseName"));&lt;br&gt;
                });&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here we tell the .Net to use EntityFramework Cosmos Provider instead of EntityFramework Sql Server provider and adding our  &lt;code&gt;StudentDbContext&lt;/code&gt;  and passing the required option to create a connection with our Cosmos DB instance.  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;DAL/StudentDbContext.cs&lt;/em&gt;  file and add the following method to&lt;br&gt;&lt;br&gt;
&lt;code&gt;StudentDbContext&lt;/code&gt;  class&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;protected override void OnModelCreating(ModelBuilder modelBuilder)&lt;br&gt;
        {&lt;br&gt;
            modelBuilder.HasDefaultContainer("Students");&lt;br&gt;
            modelBuilder.Entity().ToContainer("Students");&lt;br&gt;
        }&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;In first line we set the default Cosmos DB Container to be “Students”. In the second line we map the Student entity to  Students  Container. If we have other entities we need to map ‘em to the corresponding container as well.  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run your application and if there is no error you will see the following page in your browser  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://2.bp.blogspot.com/-1Eh0uXFVoy0/XfpUxFkLovI/AAAAAAAACeo/Oq5IcD_t8No9Bh4BwRwYwxNdODqgFTwVgCLcBGAsYHQ/s1600/home-page.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F2.bp.blogspot.com%2F-1Eh0uXFVoy0%2FXfpUxFkLovI%2FAAAAAAAACeo%2FOq5IcD_t8No9Bh4BwRwYwxNdODqgFTwVgCLcBGAsYHQ%2Fs400%2Fhome-page.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on New Item and fill the form then click Add  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://3.bp.blogspot.com/-GvnswXXZxlQ/XfpVLDr7TYI/AAAAAAAACew/YXze3i9wraYjrvlE1yDNXoCstign8Eq_wCLcBGAsYHQ/s1600/add-page.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-GvnswXXZxlQ%2FXfpVLDr7TYI%2FAAAAAAAACew%2FYXze3i9wraYjrvlE1yDNXoCstign8Eq_wCLcBGAsYHQ%2Fs400%2Fadd-page.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Congratulation, you added your student to Student Cosmos DB container  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://3.bp.blogspot.com/-njVcQ1lkqYk/XfpVbjiJJkI/AAAAAAAACe4/mLHebmyNOyAWKH19N6l5V_ghvM_ktu1-wCLcBGAsYHQ/s1600/list-page.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-njVcQ1lkqYk%2FXfpVbjiJJkI%2FAAAAAAAACe4%2FmLHebmyNOyAWKH19N6l5V_ghvM_ktu1-wCLcBGAsYHQ%2Fs400%2Flist-page.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to your Cosmos DB web page and open Data Explorer, it should look like  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://3.bp.blogspot.com/-fkk12fBHRLw/XfpVyGeCETI/AAAAAAAACfA/OCe7Gv5q--gQ7K4qOHwlD_rimayS6LYIQCLcBGAsYHQ/s1600/json-item.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-fkk12fBHRLw%2FXfpVyGeCETI%2FAAAAAAAACfA%2FOCe7Gv5q--gQ7K4qOHwlD_rimayS6LYIQCLcBGAsYHQ%2Fs400%2Fjson-item.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article we demonstrated how to create a sample DotVVM web application and connect to Azure Cosmos DB NoSQL database and perform CRUD operations as we used to do with SQL Server database or any other relational database. We have done few changes in the sample project code to twist it from using Entity Framework Code First approach (SQL Server) to use Entity Framework Code First approach (Cosmos DB).&lt;/p&gt;

&lt;p&gt;You can find the complete source code on  &lt;a href="https://github.com/miroprocessor/dotvvm-cosmosdb" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotvvm</category>
      <category>csharp</category>
      <category>cosmosdb</category>
    </item>
    <item>
      <title> DotVVM CRUD application with Cloud Firestore</title>
      <dc:creator>Amir Ismail</dc:creator>
      <pubDate>Thu, 05 Mar 2020 23:57:59 +0000</pubDate>
      <link>https://forem.com/dotvvm/dotvvm-crud-application-with-cloud-firestore-101b</link>
      <guid>https://forem.com/dotvvm/dotvvm-crud-application-with-cloud-firestore-101b</guid>
      <description>&lt;p&gt;In  &lt;a href="https://dev.to/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah"&gt;previous post&lt;/a&gt;  we demonstrated how to use DotVVM to create CRUD application with Azure Cosmos DB as your data store.&lt;/p&gt;

&lt;p&gt;In this post we will demonstrate how to do the same with Cloud Firestore by Google.&lt;/p&gt;

&lt;p&gt;To know more about DotVVM Framework you can check its  &lt;a href="https://www.dotvvm.com/" rel="noopener noreferrer"&gt;official website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Cloud Firestore?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform. It keeps your data in sync across client apps through realtime listener and offers offline support for mobile and web apps.&lt;/p&gt;

&lt;p&gt;You can know more about Cloud Firebase  &lt;a href="https://firebase.google.com/docs/firestore" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install DotVVM extension&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;refer to &lt;a href="https://dev.to/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah"&gt;previous post&lt;/a&gt; and follow the steps.&lt;/p&gt;

&lt;p&gt;To know more about the DotVVM extension visit its page on visual studio marketplace:&lt;a href="https://marketplace.visualstudio.com/items?itemName=TomasHerceg.DotVVM-VSExtension2019" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=TomasHerceg.DotVVM-VSExtension2019&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you are ready to start coding with DotVVM framework. DotVVM extension installs DotVVM sample project which we will use to demonstrate how it is easy to connect to Cloud Firestore database from DotVVM application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Cloud Firestore Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use cloud Firestore as your database you need to create a project on Firestore.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go to &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;https://console.firebase.google.com/&lt;/a&gt; and login with your google account or create new one.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on Add Project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter "&lt;strong&gt;dotvvm&lt;/strong&gt;" as project name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In next step, Disable Google Analytics for this project. It is recommended to enable it for real project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on Create Project. it will take one or two mins to create your project. When it is ready click on continue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-WV3ZiYPDAOg/Xgr5qckOqcI/AAAAAAAACiw/p2NuISo9axItYAdVnu7O9w8_CtaAQtDFwCLcBGAsYHQ/s1600/project%2Bcreated.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-WV3ZiYPDAOg%2FXgr5qckOqcI%2FAAAAAAAACiw%2Fp2NuISo9axItYAdVnu7O9w8_CtaAQtDFwCLcBGAsYHQ%2Fs200%2Fproject%252Bcreated.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From the left navigation pan, open database then click on Create database&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-vgO5StdFNBU/Xgr7UQ6gWeI/AAAAAAAACjE/kIt1SZ3IyQ8PuzY-HtEuXEr0uyorXfEKgCLcBGAsYHQ/s1600/database.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-vgO5StdFNBU%2FXgr7UQ6gWeI%2FAAAAAAAACjE%2FkIt1SZ3IyQ8PuzY-HtEuXEr0uyorXfEKgCLcBGAsYHQ%2Fs320%2Fdatabase.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the popup window, select  &lt;strong&gt;&lt;em&gt;Start in test mode&lt;/em&gt;&lt;/strong&gt; then click next.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the location of your database(you can keep the default selection) then Click Done.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Congratulation, your Cloud Firestore database is created and ready.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To be able to connect to your Firestore database from your application(server) you need to set the GOOGLE_APPLICATION_CREDENTIALS environment variable to point to JSON service account key file.&lt;/p&gt;

&lt;p&gt;To setup your service account, go to &lt;a href="https://cloud.google.com/docs/authentication/getting-started" rel="noopener noreferrer"&gt;https://cloud.google.com/docs/authentication/getting-started&lt;/a&gt; and follow the instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DotVVM Web Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://miroprocessordev.blogspot.com/2019/12/dotvvm-crud-application-with-entity.html" rel="noopener noreferrer"&gt;previous post&lt;/a&gt; you can find the complete steps for creating DotVVM web application. In this post we focus on code changes required to connect to Firestore database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Uninstall entity framework Sql Server related nuget package
&lt;code&gt;Microsoft.EntityFrameworkCore.SqlServer&lt;/code&gt;  and  &lt;code&gt;Microsoft.EntityFrameworkCore&lt;/code&gt;
As we will connect to Cloud Firestore database not Sql Server database&lt;/li&gt;
&lt;li&gt;  Install  &lt;code&gt;Google.Cloud.Firestore&lt;/code&gt;  nuget package. This package is required to run CRUD operations against your firestore database from your web application.&lt;/li&gt;
&lt;li&gt;  Open  &lt;em&gt;appsettings.json&lt;/em&gt;  file and remove the connection string. keeping it will not harm but we need our code to be clean.&lt;/li&gt;
&lt;li&gt;  Delete  &lt;em&gt;DAL/StudentDbContext.cs&lt;/em&gt;  file.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;Startup.cs&lt;/em&gt;  file and delete the following lines&lt;/p&gt;

&lt;p&gt;&lt;code&gt;services.AddEntityFrameworkSqlServer()&lt;br&gt;
                .AddDbContext&amp;lt;Studentdbcontext&amp;gt;(options =&amp;gt;&lt;br&gt;
                {&lt;br&gt;
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));&lt;br&gt;
                });&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;DAL/Entities/Student.cs&lt;/em&gt;  file and add the following using statement&lt;/p&gt;

&lt;p&gt;&lt;code&gt;using Google.Cloud.Firestore;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decorate the Student class with &lt;code&gt;[FirestoreData]&lt;/code&gt;  attribute and each property with &lt;code&gt;[FirestoreProperty]&lt;/code&gt;  attribute. Also change the type of &lt;code&gt;EnrollmentDate&lt;/code&gt;  property to  Timestamp  instead of  &lt;code&gt;DateTime&lt;/code&gt;. The complete code of Student class will be&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;[FirestoreData]&lt;br&gt;
 public class Student&lt;br&gt;
 {&lt;br&gt;
     [FirestoreProperty]&lt;br&gt;
     public int Id { get; set; }&lt;br&gt;
     [FirestoreProperty]&lt;br&gt;
     public string FirstName { get; set; }&lt;br&gt;
     [FirestoreProperty]&lt;br&gt;
     public string LastName { get; set; }    &lt;br&gt;
     [FirestoreProperty]&lt;br&gt;
     public string About { get; set; }    &lt;br&gt;
     [FirestoreProperty]&lt;br&gt;
     public Timestamp EnrollmentDate { get; set; }&lt;br&gt;
 }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Those attributes are required and used to serialize/deserialize your entities from and to json objects. &lt;code&gt;Timestamp&lt;/code&gt;  is the Firestore datatype used to represent date/time values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Open  &lt;em&gt;Services/StudentService.cs&lt;/em&gt;  file and add the following private properties to  &lt;code&gt;StudentService&lt;/code&gt;  class&lt;/p&gt;

&lt;p&gt;&lt;code&gt;private const string project = "dotvvm";&lt;br&gt;
private const string collection = "students";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;where  project  is the name of your Firestore project and collection  is the name of your database collection where you will insert/retrieve records&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the &lt;code&gt;GetAllStudentsAsync&lt;/code&gt;  method with the following&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public async Task&amp;lt;List&amp;lt;StudentListModel&amp;gt;&amp;gt; GetAllStudentsAsync()&lt;br&gt;
{&lt;br&gt;
     var studentsList = new List&amp;lt;Student&amp;gt;();&lt;br&gt;
     FirestoreDb db = FirestoreDb.Create(Project);&lt;br&gt;
     Query allStudentsQuery = db.Collection(Collection);    &lt;br&gt;
     QuerySnapshot allStudentsQuerySnapshot = await allStudentsQuery.GetSnapshotAsync();&lt;br&gt;
     foreach (DocumentSnapshot documentSnapshot in allStudentsQuerySnapshot.Documents)&lt;br&gt;
     {&lt;br&gt;
         studentsList.Add(documentSnapshot.ConvertTo&amp;lt;Student&amp;gt;());&lt;br&gt;
     }    &lt;br&gt;
     return studentsList.Select(&lt;br&gt;
            s =&amp;gt; new StudentListModel&lt;br&gt;
                {&lt;br&gt;
                    Id = s.Id,&lt;br&gt;
                    FirstName = s.FirstName,&lt;br&gt;
                    LastName = s.LastName&lt;br&gt;
                }&lt;br&gt;
            ).ToList();&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the &lt;code&gt;GetStudentByIdAsync&lt;/code&gt;  method with the following&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public async Task&amp;lt;StudentListModel&amp;gt; GetStudentByIdAsync()&lt;br&gt;
{&lt;br&gt;
     FirestoreDb db = FirestoreDb.Create(Project);&lt;br&gt;
     Query docRef = db.Collection(Collection).WhereEqualTo("Id", studentId).Limit(1);&lt;br&gt;
     QuerySnapshot snapshot = await docRef.GetSnapshotAsync();&lt;br&gt;
     if (snapshot.Count &amp;gt; 0)&lt;br&gt;
     {&lt;br&gt;
          Student student = snapshot.ElementAt(0).ConvertTo&amp;lt;Student&amp;gt;();&lt;br&gt;
          return new StudentDetailModel()&lt;br&gt;
          {&lt;br&gt;
              About = student.About,&lt;br&gt;
              EnrollmentDate = student.EnrollmentDate.ToDateTime(),&lt;br&gt;
              FirstName = student.FirstName,&lt;br&gt;
              Id = student.Id,&lt;br&gt;
              LastName = student.LastName&lt;br&gt;
          };&lt;br&gt;
      }&lt;br&gt;
      else&lt;br&gt;
      {&lt;br&gt;
           return null;&lt;br&gt;
      }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the  &lt;code&gt;UpdateStudentAsync&lt;/code&gt; method with the following&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public async Task UpdateStudentAsync(StudentDetailModel student)&lt;br&gt;
{&lt;br&gt;
     FirestoreDb db = FirestoreDb.Create(Project);&lt;br&gt;
     Query docRef = db.Collection(Collection).WhereEqualTo("Id", student.Id).Limit(1);&lt;br&gt;
     QuerySnapshot snapshot = await docRef.GetSnapshotAsync();&lt;br&gt;
     if (snapshot.Count &amp;gt; 0)&lt;br&gt;
     {&lt;br&gt;
           DocumentReference studentRef = db.Collection(Collection).Document(snapshot.ElementAt(0).Id);&lt;br&gt;
           Dictionary&amp;lt;string, object&amp;gt; updates = new Dictionary&amp;lt;string, object&amp;gt;&lt;br&gt;
           {&lt;br&gt;
               { nameof(student.About), student.About},&lt;br&gt;
               { nameof(student.EnrollmentDate), Timestamp.FromDateTime(student.EnrollmentDate.ToUniversalTime())},&lt;br&gt;
               { nameof(student.FirstName), student.FirstName},&lt;br&gt;
               { nameof(student.LastName), student.LastName}&lt;br&gt;
           };&lt;br&gt;
           await studentRef.UpdateAsync(updates);&lt;br&gt;
     }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the  &lt;code&gt;InsertStudentAsync&lt;/code&gt;  method with the following&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public async Task InsertStudentAsync(StudentDetailModel student)&lt;br&gt;
{&lt;br&gt;
     var entity = new Student()&lt;br&gt;
     {&lt;br&gt;
          Id = new Random().Next(1, int.MaxValue),&lt;br&gt;
          FirstName = student.FirstName,&lt;br&gt;
          LastName = student.LastName,&lt;br&gt;
          About = student.About,&lt;br&gt;
          //create Timestamp from DateTime value&lt;br&gt;
          EnrollmentDate = Timestamp.FromDateTime(student.EnrollmentDate.ToUniversalTime())&lt;br&gt;
     };    &lt;br&gt;
     FirestoreDb db = FirestoreDb.Create(Project);&lt;br&gt;
     var Id = Guid.NewGuid().ToString();&lt;br&gt;
     DocumentReference docRef = db.Collection(Collection).Document(Id);&lt;br&gt;
     await docRef.SetAsync(entity);&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace the  &lt;code&gt;DeleteStudentAsync&lt;/code&gt;  method with the following&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public async Task DeleteStudentAsync(int studentId)&lt;br&gt;
{&lt;br&gt;
     FirestoreDb db = FirestoreDb.Create(Project);&lt;br&gt;
     Query docRef = db.Collection(Collection).WhereEqualTo("Id", studentId).Limit(1);&lt;br&gt;
     QuerySnapshot snapshot = await docRef.GetSnapshotAsync();&lt;br&gt;
     if (snapshot.Count &amp;gt; 0)&lt;br&gt;
     {&lt;br&gt;
         DocumentReference studentRef = db.Collection(Collection).Document(snapshot.ElementAt(0).Id);&lt;br&gt;
         await studentRef.DeleteAsync();&lt;br&gt;
     }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run your application and if there is no error you will see the following page in your browser  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://2.bp.blogspot.com/-1Eh0uXFVoy0/XfpUxFkLovI/AAAAAAAACeo/Oq5IcD_t8No9Bh4BwRwYwxNdODqgFTwVgCLcBGAsYHQ/s1600/home-page.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F2.bp.blogspot.com%2F-1Eh0uXFVoy0%2FXfpUxFkLovI%2FAAAAAAAACeo%2FOq5IcD_t8No9Bh4BwRwYwxNdODqgFTwVgCLcBGAsYHQ%2Fs400%2Fhome-page.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on New Item and fill the form then click Add&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-cNa1jdHipZQ/Xg3QfXks5VI/AAAAAAAACjg/pkLHgcyPyJUCJnrANLVnIY67XDS1e8EqACLcBGAsYHQ/s1600/Create.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-cNa1jdHipZQ%2FXg3QfXks5VI%2FAAAAAAAACjg%2FpkLHgcyPyJUCJnrANLVnIY67XDS1e8EqACLcBGAsYHQ%2Fs320%2FCreate.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Congratulation, you added your student to students Firestore collection&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-d2NYpRR0zDg/Xg3QyBaVW3I/AAAAAAAACjo/mWoWfW46nO0oUEPn-tv3t_cYa5D8T1lsACLcBGAsYHQ/s1600/List.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-d2NYpRR0zDg%2FXg3QyBaVW3I%2FAAAAAAAACjo%2FmWoWfW46nO0oUEPn-tv3t_cYa5D8T1lsACLcBGAsYHQ%2Fs320%2FList.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to your Firestore database, it should look like&lt;/p&gt;

&lt;p&gt;&lt;a href="https://1.bp.blogspot.com/-3QXY5yUIzCg/Xg3RCFfkqII/AAAAAAAACjw/_ePZNiLXXTUB01XUZT82umzhiAYW21Z4gCLcBGAsYHQ/s1600/record.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F1.bp.blogspot.com%2F-3QXY5yUIzCg%2FXg3RCFfkqII%2FAAAAAAAACjw%2F_ePZNiLXXTUB01XUZT82umzhiAYW21Z4gCLcBGAsYHQ%2Fs320%2Frecord.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;notice that, Firestore is created a student collection and inserted your student entity as  &lt;code&gt;JSON&lt;/code&gt;  document and also notice how it represents the  &lt;code&gt;EnrollmentDate&lt;/code&gt; value as timestamp.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article we demonstrated how to create a sample DotVVM web application, Cloud Firestore database and perform CRUD operations as we used to do with SQL Server database or any other relational database. We have done changes in the sample project code to twist it from using Entity Framework Code First approach (SQL Server) to use Google Cloud FireStore .Net SDK.&lt;/p&gt;

&lt;p&gt;You can find the complete source code on  &lt;a href="https://github.com/miroprocessor/dotvvm-firestore" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>dotvvm</category>
      <category>firebase</category>
    </item>
  </channel>
</rss>
