Thursday, 22 January 2026

Add ,Edit and Delete in GridView with People picker and DateTime Picker control

Add ,Edit and Delete in GridView with People picker and DateTime Picker control

using System;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Data;
using System.IO;
using System.Collections;
namespace CustomPageForLibrary.Layouts.CustomPageForLibrary
{
    public partial class TaskFormForLirary : LayoutsPageBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                DropDownBind();
                BindData();
             
             
            }
        }
        protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
        {
           
            GridView1.EditIndex = e.NewEditIndex;
            BindData();
        }
        protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            int i = e.RowIndex;

            //using (SPSite site = new SPSite("siteurl"))
            using (SPSite site = new SPSite(SPContext.Current.Web.Url))
            {
                site.AllowUnsafeUpdates = true;
                using (SPWeb web = site.OpenWeb())
                {
                    web.AllowUnsafeUpdates = true;
                    SPList list = web.Lists["MOMListt"];
                    int id = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Value);
                    SPListItem item = list.GetItemById(id);
               
                  //  item["Meeting"] = new SPFieldLookupValue(Convert.ToInt32(txtMeetingId.Text),txtMeetingName.Text);
                    item["Minutes"] = ((TextBox)GridView1.Rows[i].FindControl("txtMinutes")).Text;
                    PeopleEditor ppAuthor = ((PeopleEditor)GridView1.Rows[i].FindControl("ActionByUser"));
                    PickerEntity ActionUser = (PickerEntity)ppAuthor.ResolvedEntities[0];
                    SPUser actionByUser = Web.EnsureUser(ActionUser.Key);
                    item["Actionby"] = actionByUser;
                    if (((DateTimeControl)GridView1.Rows[i].FindControl("targetdateuser")).SelectedDate.Date.ToString() != "" || ((DateTimeControl)GridView1.Rows[i].FindControl("targetdateuser")).SelectedDate.Date.ToString() !=null)
                    {
                    item["TargetDate"] = ((DateTimeControl)GridView1.Rows[i].FindControl("targetdateuser")).SelectedDate.Date;
                    }
                    item["Status"] = ((DropDownList)GridView1.Rows[i].FindControl("DropDownList1")).SelectedItem.Text;
                    CheckBox chk = ((CheckBox)GridView1.Rows[i].FindControl("Assigned"));
                    string blActive = "";
                    if (chk.Checked == true)
                    {
                        blActive = "True";
                        item["assignedtask"] = blActive;
                    }
                    else
                    {
                        blActive = "False";
                        item["assignedtask"] = blActive;
                    }
                    item["Issues"] = TextBox7.Text;
                    item.Update();
                    web.AllowUnsafeUpdates = false;
                }
                site.AllowUnsafeUpdates = false;

            }
            GridView1.EditIndex = -1;
            BindData();
        }
        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            DataRowView drview = e.Row.DataItem as DataRowView;
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                if ((e.Row.RowState & DataControlRowState.Edit) > 0)
                {
                    SPSite site = new SPSite(SPContext.Current.Web.Url);
                    SPWeb web = site.OpenWeb();
                    PeopleEditor pplEditor = ((PeopleEditor)e.Row.FindControl("ActionByUser"));
                    ArrayList alApprover = new ArrayList();
                    PickerEntity pentApprover = new PickerEntity();
                    char[] delimiterChars = { '#' };
                    string text = drview[2].ToString();
                    string[] words = text.Split(delimiterChars);
                    pentApprover.Key = words[1];
                    alApprover.Add(pentApprover);
                    pplEditor.UpdateEntities(alApprover);
                    DateTimeControl dtc = ((DateTimeControl)e.Row.FindControl("targetdateuser"));
                    dtc.SelectedDate=Convert.ToDateTime(drview[3].ToString());
                    DropDownList dpEmpdept = (DropDownList)e.Row.FindControl("DropDownList1");
                    DataTable dt = GetStatus();
                    dpEmpdept.DataSource = GetStatus();
                    dpEmpdept.DataTextField = "DepName";
                    dpEmpdept.DataValueField = "DepName";
                    dpEmpdept.DataBind();
                    dpEmpdept.SelectedValue = drview[4].ToString();
                    CheckBox chkb = (CheckBox)e.Row.FindControl("Assigned");
                    if (drview[5].ToString() == "True")
                    { chkb.Checked = true; }
                    else { chkb.Checked = false; }
             
                }
            }
            if (e.Row.RowType == DataControlRowType.Footer)
            {
                DropDownList dp = (DropDownList)e.Row.FindControl("DropDownList14");
                dp.DataSource = GetStatus();
                dp.DataTextField = "DepName";
                dp.DataValueField = "DepName";
                dp.DataBind();
            }
        }
        private DataTable GetStatus()
        {
           
            DataTable dt = new DataTable();
            dt.Columns.Add("DepName");
            DataRow rw1 = dt.NewRow();
            rw1[0] = "Open";
            dt.Rows.Add(rw1);
            DataRow rw2 = dt.NewRow();
            rw2[0] = "Closed";
            dt.Rows.Add(rw2);
            return dt;
        }
        protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            GridView1.EditIndex = -1;

            BindData();

        }
        protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            int i = e.RowIndex;
           // BindData();
        }
        public void BindData()
        {
            using (SPSite s = new SPSite(SPContext.Current.Web.Url))
            {
                using (SPWeb sw = s.OpenWeb())
                {
                    SPList sl = sw.Lists["MOMListt"];
                    SPQuery query=new SPQuery();
                    if (txtMeetingId.Text != "")
                    {
                        query.Query = @"<Where>" +
          "<Eq>" +
             "<FieldRef Name='Meeting' LookupId='True' />" +
             "<Value Type='Lookup'>" + Convert.ToInt32(txtMeetingId.Text) + "</Value>" +
          "</Eq>" +
       "</Where>";
                    }
                    SPListItemCollection itemCollection = sl.GetItems(query);
                    DataTable ResTable = new DataTable();
                    ResTable.Columns.Add(new DataColumn("ID"));
                    ResTable.Columns.Add(new DataColumn("Minutes"));
                    ResTable.Columns.Add(new DataColumn("Actionby"));
                    ResTable.Columns.Add(new DataColumn("TargetDate"));
                    ResTable.Columns.Add(new DataColumn("Status"));
                    ResTable.Columns.Add(new DataColumn("TaskAssigned"));
               
                    foreach (SPListItem item in itemCollection)
                    {
                        DataRow dr = ResTable.NewRow();
                        dr["ID"] = item["ID"].ToString();
                        dr["Minutes"] = item["Minutes"];
                        dr["ActionBy"] = item["Actionby"].ToString();
                        dr["TargetDate"] = item["TargetDate"];
                        dr["Status"] = item["Status"].ToString();
                        dr["TaskAssigned"] = item["assignedtask"].ToString();
                        ResTable.Rows.Add(dr);
                    }
                    if (ResTable.Rows.Count > 0)
                    {
                        GridView1.DataSource = ResTable;
                        GridView1.DataBind();
                     
                    }
                    else
                    {
                        DataRow dr = ResTable.NewRow();
                        dr["ID"] = "";
                        dr["Minutes"] = "";
                        dr["ActionBy"] = "";
                        dr["TargetDate"] = "";
                        dr["Status"] = "";
                        dr["TaskAssigned"] = "";
                        ResTable.Rows.Add(dr);
                        GridView1.DataSource = ResTable;
                        GridView1.DataBind();
                    }
                 
                }
            }
        }
     
       
        public void DropDownBind()
        {
            using (SPSite site = new SPSite(SPContext.Current.Web.Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    DataSet ds = new DataSet();
                    SPList list = web.Lists["Board Events"];
                    SPListItem item = list.Items.GetItemById(Convert.ToInt32(Request.QueryString["Mid"].ToString()));
                    txtMeetingName.Text = item["Title"].ToString();
                    txtMeetingId.Text = item["ID"].ToString();
                 
                }
            }
        }
     
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Add")
            {
                using (SPSite site = new SPSite(SPContext.Current.Web.Url))
                {
                    site.AllowUnsafeUpdates = true;
                    using (SPWeb web = site.OpenWeb())
                    {
                        web.AllowUnsafeUpdates = true;
                        SPList list = web.Lists["MOMListt"];
                        SPListItem item = list.Items.Add();
                        item["Meeting"] = new SPFieldLookupValue(Convert.ToInt32(txtMeetingId.Text), txtMeetingName.Text);
                        item["Minutes"] = ((TextBox)GridView1.FooterRow.FindControl("txtMinuteFooter")).Text;
                        PeopleEditor ppAuthor = ((PeopleEditor)GridView1.FooterRow.FindControl("ActionBy"));
                        PickerEntity ActionUser = (PickerEntity)ppAuthor.ResolvedEntities[0];
                        SPUser actionByUser = Web.EnsureUser(ActionUser.Key);
                        item["Actionby"] = actionByUser;
                        item["TargetDate"] = ((DateTimeControl)GridView1.FooterRow.FindControl("targetdate")).SelectedDate.Date;
                        item["Status"] = ((DropDownList)GridView1.FooterRow.FindControl("DropDownList14")).SelectedItem.Text;
                        CheckBox chk = ((CheckBox)GridView1.FooterRow.FindControl("AssignedFilter"));
                        string blActive = "";
                        if (chk.Checked == true)
                        {
                            blActive = "True";
                            item["assignedtask"] = blActive;
                        }
                        else
                        {
                            blActive = "False";
                            item["assignedtask"] = blActive;
                        }
                        if (TextBox7.Text != "")
                        {
                            item["Issues"] = TextBox7.Text;
                        }
                        item.Update();
                        web.AllowUnsafeUpdates = false;
                    }
                    site.AllowUnsafeUpdates = false;
               
                }
                BindData();
            }
            else if (e.CommandName == "Delete")
         {
             using (SPSite site = new SPSite(SPContext.Current.Web.Url))
           {
                site.AllowUnsafeUpdates = true;
                using (SPWeb web = site.OpenWeb())
                {
                    web.AllowUnsafeUpdates = true;
                 
                    SPList taskList = web.Lists["Tasks"];
                    SPQuery query = new SPQuery();
                    query.Query = @"<Where>" +
         "<Eq>" +
            "<FieldRef Name='MinuteofMeetingId'/>" +
            "<Value Type='Number'>" + Convert.ToInt32(e.CommandArgument.ToString()) + "</Value>" +
         "</Eq>" +
      "</Where>";

                    SPListItemCollection itemcollection = taskList.GetItems(query);

                    for (int i = itemcollection.Count - 1; i >= 0; i--)
                    {
                        SPListItem item = itemcollection[i];
                        item.Delete();
                    }
                    SPList list = web.Lists["MOMListt"];
                    list.Items.DeleteItemById(Convert.ToInt32(e.CommandArgument.ToString()));
                    web.AllowUnsafeUpdates = false;
                }
                site.AllowUnsafeUpdates = false;
           }
             BindData();
             
        }
         

        }
     

       
    }
}


HTML Code///////////////////////////////////////////////////////////////////////////////////////////////
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TaskFormForLirary.aspx.cs" Inherits="CustomPageForLibrary.Layouts.CustomPageForLibrary.TaskFormForLirary" DynamicMasterPageFile="~masterurl/default.master" %>

<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<style type="text/css">
        #DivContent
        {
            margin-top: 30px;
            width: 85%;
            border: .1em;
            border-style: none;
            padding: 15px;
        }
        table
        {
            width: 100%;
        }
        .ControlTD
        {
            width: 20%;
            text-align: left;
        }
        .TextTD
        {
            width: 25%;
            font-size: 12px;
            text-align: left;
            color: #00A1DE;
        }
        .RFVTD
        {
            width: 10%;
            text-align: left;
        }
        p
        {
            text-align: center;
            font-size: 22px;
            color: #3C8A2E;
        }
    </style>
    <script language="javascript" type="text/javascript">

        function ValidateGrid(x) {

            var gridView = document.getElementById('<%=GridView1.ClientID %>');

            var selectedRowIndex = x.parentNode.parentNode.rowIndex;

            var txtName = gridView.rows[parseInt(selectedRowIndex)].cells[0].children[0];

             var pplpicker = gridView.rows[parseInt(selectedRowIndex)].cells[1].children[0];

            if (txtName.value == "" || pplpicker.value=="")
            {

                alert('Please input all required fields');

                return false;

            }

        }

    </script>
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">

<div id="DivContent">
        <p>
            Minutes of Meeting</p>
            <div><div>&nbsp; Meeting&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
               <%-- <asp:DropDownList ID="DropDownList2" runat="server" style="margin-left: 0px" Width="309px">
                </asp:DropDownList>--%>
                <asp:Label ID="txtMeetingName" runat="server"  Font-Bold="true">
                </asp:Label><asp:Label ID="txtMeetingId" runat="server"
                     ForeColor="White"></asp:Label>
                   
                </div></div>
                <asp:UpdatePanel ID="Panel" runat="server" >
            <ContentTemplate>
            <br />
            <br />
         <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID"
    EnableModelValidation="True" ShowFooter="True" OnRowEditing="GridView1_RowEditing" OnRowCancelingEdit="GridView1_RowCancelingEdit" OnRowCommand="GridView1_RowCommand" OnRowDeleting="GridView1_RowDeleting" OnRowUpdating="GridView1_RowUpdating" OnRowDataBound="GridView1_RowDataBound"  >
    <Columns>
        <asp:TemplateField HeaderText="Minutes">
            <EditItemTemplate>
                <asp:TextBox ID="txtMinutes" runat="server" Text='<%#Eval("Minutes")%>' TextMode="MultiLine" Width="350px" Height="70px"></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%#Eval("Minutes")%>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
         <asp:TextBox ID="txtMinuteFooter" runat="server" TextMode="MultiLine" Width="350px" Height="70px"></asp:TextBox>
     
        </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Action By">
            <EditItemTemplate>
                <SharePoint:PeopleEditor ID="ActionByUser" runat="server" MultiSelect="false" Width="200px" AllowEmpty="false"  />
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" Text='<%#Eval("ActionBy")%>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                 <SharePoint:PeopleEditor ID="ActionBy" runat="server" MultiSelect="false" Width="200px" AllowEmpty="false"  />
        </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Target Date" ItemStyle-Width="150px">
            <EditItemTemplate>
           
                <SharePoint:DateTimeControl EnableViewState="true" ID="targetdateuser" runat="server"
                        DateOnly="true" />
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label3" runat="server" Text='<%#Eval("TargetDate")%>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
                 <SharePoint:DateTimeControl EnableViewState="true" ID="targetdate" runat="server"
                        DateOnly="true" />
        </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Status">
            <EditItemTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server">
             
               
                </asp:DropDownList>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label ID="Label4" runat="server" Text='<%#Eval("Status")%>'></asp:Label>
            </ItemTemplate>
            <FooterTemplate>
         <asp:DropDownList ID="DropDownList14" runat="server">
             
                </asp:DropDownList>
        </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Assigned Task">
            <EditItemTemplate>
               <asp:CheckBox ID="Assigned" runat="server">
             
                </asp:CheckBox>
            </EditItemTemplate>
            <ItemTemplate>
              <asp:Label ID="Label5" runat="server" Text='<%#Eval("TaskAssigned")%>'></asp:Label>
           
           
            </ItemTemplate>
            <FooterTemplate>
         <asp:CheckBox ID="AssignedFilter" runat="server" >
                </asp:CheckBox>
        </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField ShowHeader="False">
            <EditItemTemplate>
                <asp:LinkButton ID="LinkButton11" runat="server" CausesValidation="true" OnClientClick='javascript:return ValidateGrid(this);'
                    CommandName="Update" Text="Update" CommandArgument='<%#Eval("ID")%>'></asp:LinkButton>
                &nbsp;<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
                    CommandName="Cancel" Text="Cancel"></asp:LinkButton>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
                    CommandName="Edit" Text="Edit"></asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
         
                <asp:LinkButton ID="LinkButton2s" runat="server" CausesValidation="False"
                    CommandName="Delete" Text="Delete" CommandArgument='<%#Eval("ID")%>'></asp:LinkButton>

            </ItemTemplate>
            <FooterTemplate>
             <asp:LinkButton ID="LinkButton21" runat="server"
                    CommandName="Add" Text="Add" CausesValidation="true" OnClientClick='javascript:return ValidateGrid(this);'></asp:LinkButton>
            </FooterTemplate>
        </asp:TemplateField>

    </Columns>
 
</asp:GridView>
    </ContentTemplate>
    </asp:UpdatePanel>
<div>
    <table>
        <tr>
            <td valign="top">Pending Issues :</td><td>
                <asp:TextBox ID="TextBox7" runat="server" TextMode="MultiLine" Height="84px" Width="534px"></asp:TextBox></td>

        </tr>

    </table>

</div>
        <br />
        <p>
            &nbsp;</p>
    </div>

</asp:Content>

<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Application Page
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
My Application Page
</asp:Content>

How to get and set TextField value in react


How to get and set TextField value in react spfx webpart ?

1.      Add React Webpart
2.      Once your webpart is ready then open .tsx file from component folder and  Import react component module  in your webpart
import {Label, TextField} from 'office-ui-fabric-react';
3.      Check below code step by step to get and set textfield state in react



import * as React from 'react';
import styles from './ReactDemo.module.scss';
import { IReactDemoProps } from './IReactDemoProps';
import { escape } from '@microsoft/sp-lodash-subset';

//step1 import fabric react module, add label and textfield refrence
import {Label,TextField} from 'office-ui-fabric-react';
//step2 create a interface for controls
export interface IControls
{
  FirstName:string;
  LastName:string;
}
//step3 replace IControls Interface with {}
export default class ReactDemo extends React.Component<IReactDemoProps,IControls> {
  //step4 add a constructor
constructor(props)
{
  //step5 define the super method
  super(props);
  //step6 intialize control state to set the default value on page load
  this.state={
    FirstName:"Mohammed",
    LastName:"Waseem"
  };

  //step9 bind event onchange
  this.FirstNameonchanged=this.FirstNameonchanged.bind(this);
  this.LastNameOnChanged=this.LastNameOnChanged.bind(this);
}

//step7 and 10 add controls in render method
  public render(): React.ReactElement<IReactDemoProps> {
    return (
      <div className={ styles.reactDemo }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <Label className={styles.label}>FirstName</Label>
              <TextField value={this.state.FirstName} onChanged={this.FirstNameonchanged}></TextField>
              <Label className={styles.label}>LastName</Label>
              <TextField value={this.state.LastName} onChanged={this.LastNameOnChanged}></TextField>
            </div>
          </div>
        </div>
      </div>
    );
  }


Result1: default value on page load




  //step8 to set the state value on changed in textfield
  private FirstNameonchanged(firstname:any)
  {
    this.setState({FirstName:firstname});
    console.log("FirstName state value is : "+this.state.FirstName);
  }
  private LastNameOnChanged(lastname:any)
  {
    this.setState({LastName:lastname});
    console.log("LastName state value is:"+this.state.LastName);
  }
}

Result 2 :Changed value











How to get and set People Picker value in react spfx webpart


How to get and set People Picker value in react spfx webpart ?

1.      Add React Webpart as ReactDemo
2.      Open IReactDemoProps.ts file from webpart component folder and  add webpartcontext in webpart interface
import { WebPartContext } from "@microsoft/sp-webpart-base";
// add WebPartContext context on webpart
export interface IReactDemoProps {
                description: string;
                context:WebPartContext;
}
3.      then open .tsx file from component folder
Check below code step by step to add people picker control

import * as React from 'react';
import styles from './ReactDemo.module.scss';
import { IReactDemoProps } from './IReactDemoProps';
import { escape } from '@microsoft/sp-lodash-subset';

//step1 import fabric react, pnp-spfx,pnp  module and, add label and button refrence
import {Label,PrimaryButton} from 'office-ui-fabric-react';
//if this modules is not installed then use the command to install 'npm install @pnp/spfx-controls-react --save'
import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
import pnp from 'sp-pnp-js';

//step2 create a interface for controls
export interface IControls
{
  pplControl:any;
}

export interface IPeoplePickerControl
{
  id:string;
  secondaryText:string;
  text:string;
}

//step3 replace IControls Interface with {}
export default class ReactDemo extends React.Component<IReactDemoProps,IControls> {
  //step4 add a constructor
constructor(props)
{
  //step5 define the super method
  super(props);
  //step6 intialize control state to set the default value on page load
  this.state={
    pplControl:[]
  };

  //step9 bind event onchange
  this.PeoplePickerItems=this.PeoplePickerItems.bind(this);
  this.ButtonClick=this.ButtonClick.bind(this);
}

//step7 and 10 add controls in render method
  public render(): React.ReactElement<IReactDemoProps> {
pnp.setup({
  spfxContext:this.props.context
});
    return (
      <div className={ styles.reactDemo }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <Label className={styles.label}>People Picker</Label>
              <PeoplePicker
                context={this.props.context}
                titleText="People Picker"
                personSelectionLimit={3}
                groupName={""} // Leave this blank in case you want to filter from all users
                showtooltip={false}
                isRequired={true}
                disabled={false}
                selectedItems={this.PeoplePickerItems}
                showHiddenInUI={false}
                principalTypes={[PrincipalType.User]}
                resolveDelay={1000}
                />
                <PrimaryButton className={styles.button} onClick={this.ButtonClick} >Get People Picker Value</PrimaryButton>
            </div>
          </div>
        </div>
      </div>
    );
  }
  //step8 to set the state value on changed in people picker control
  private PeoplePickerItems(items: any[])
  {
    this.setState({pplControl:items});
  }
//get people picker value on button click
  private ButtonClick()
  {
   let pplValue:IPeoplePickerControl[]=this.state.pplControl;
   pplValue.forEach(ppl=>
    {
           //get user’s id
                alert(ppl.id);
    });
  }
}

Result:è




Share a Document using Rest API

function shareDocumentWithOtherUsers()
{
  //  var hostweburl = decodeURIComponent('https://cbcd.sharepoint.com');
   // var appweburl = decodeURIComponent('https://abcd.sharepoint.com/sites/ssss/vvvv');
    var restSource = myCompanyUrl + "/_api/SP.Sharing.DocumentSharingManager.UpdateDocumentSharingInfo";
    $.ajax(
    {
        'url': restSource,
        'method': 'POST',
        'data': JSON.stringify({
            'resourceAddress': 'https://abcd.sharepoint.com/sites/ssss/vvvv/LibraryName/Before%20you%20ca%20djshjd.png',
            'userRoleAssignments': [{
                '__metadata': {
                    'type': 'SP.Sharing.UserRoleAssignment'
                },
                'Role': 1,
                'UserId': 'aaaa.ssss@ddddd.com'
            }],
            'validateExistingPermissions': false,
            'additiveMode': true,
            'sendServerManagedNotification': true,
            'customMessage': "Please look at the following document",
            'includeAnonymousLinksInNotification': true
        }),
        'headers': {
            'accept': 'application/json;odata=verbose',
            'content-type': 'application/json;odata=verbose',
            'X-RequestDigest': $('#__REQUESTDIGEST').val()
        },
        'success': function (data) {
            var d = data;
            console.log(d);
        },
        'error': function (err)
        {
            alert(JSON.stringify(err));
        }
    });
}

Wednesday, 21 January 2026

ERR_SSL_PROTOCOL_ERROR in spfx workbench

Issue error on local workbaench:


This site can’t provide a secure connection localhost sent an invalid response.
Try running Windows Network Diagnostics.
ERR_SSL_PROTOCOL_ERROR

Solution:

1.Open package.json file
2. go to below section

before

  "scripts": {
    "build": "gulp bundle",
    "clean": "gulp clean",
    "test": "gulp test"
  }

and add "dev" : "set NODE_NO_HTTP2=1&& gulp serve",

after

  "scripts": {
    "build": "gulp bundle",
    "clean": "gulp clean",
    "test": "gulp test",
    "dev" : "set NODE_NO_HTTP2=1&& gulp serve"
  }

3.  Run "npm run dev" command in terminal or command window
4. if you  still face the issue then run command "gulp trust-dev-cert" then run "npm run dev" command

React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration

When we  build the PCF project and  receive below warning  

Error:

Warning: React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration .

[4:47:40 PM] [start]  Compiling and bundling control...



Solution : Open the ".eslintrc.json" and add below configuration 


"settings": {

      "react": {

        "version": "detect"

      }

    }



Dynamics CRM and Model-Driven Apps in Power Apps: The Complete, No-Fluff Guide

Dynamics CRM and model-driven app in Power Apps are core pieces of Microsoft’s business application stack that help teams design scalable, secure, and data-driven solutions with minimal code. This guide explains what each is, how they connect, when to use them, and how to get started—complete with practical examples.

What is Dynamics CRM (Dynamics 365 Customer Engagement)?

Originally known as Dynamics CRM, Microsoft now delivers these capabilities through Dynamics 365 Customer Engagement (CE) apps like Sales, Customer Service, and Marketing. These apps run on Microsoft Dataverse, offering standardized tables (Accounts, Contacts, Leads, Opportunities, Cases) and robust features like security roles, business process flows, audit history, and integration with Microsoft 365 and Azure.

  • Purpose-built apps: Sales pipeline, service case management, field service, and more.
  • Enterprise-grade platform: Role-based security, activity tracking, SLA management, and analytics.
  • Extensible: Customize with Power Platform (Power Apps, Power Automate, Power BI) and Azure services.

What is a Model-Driven App in Power Apps?

A model-driven app is a Power Apps application generated from your data model in Dataverse. Instead of pixel-perfect canvas design, you define tables, columns, relationships, forms, views, charts, dashboards, and the app renders responsive UI automatically across devices.

  • Metadata-driven: Configure data structure and business rules; the UI follows.
  • Built-in UX patterns: Grids, forms, advanced filtering, and command bar actions.
  • Process automation: Business rules, business process flows (BPFs), and Power Automate flows.

How Dynamics CRM and Model-Driven Apps Work Together

Dynamics 365 CE apps are essentially first-party model-driven apps built on Dataverse with Microsoft’s prebuilt tables and logic. You can extend these apps or create your own model-driven apps alongside them to address specialized processes—reusing the same security, data, and automation framework.

  • Shared data: Use Accounts, Contacts, and custom tables in both Dynamics 365 and your model-driven apps.
  • Unified security: Apply the same roles, field security, and auditing across apps.
  • Coexistence: Extend Sales or Customer Service with custom model-driven apps for unique teams or regions.

Model-Driven Apps vs. Canvas Apps

  • Model-driven apps: Best for data-intensive processes, standardized UIs, enterprise security, and rapid configuration.
  • Canvas apps: Best for tailored, pixel-perfect experiences, task apps, and multi-connector mashups.
  • Hybrid approach: Use model-driven for core records and processes; embed canvas components for specialized screens.

When to Use Model-Driven Apps

  • Complex data relationships: Many related tables (e.g., Accounts → Opportunities → Quotes).
  • Strict governance: Need audit trails, role-based access, field-level security, and compliance.
  • Process-centric work: Guided stages with approvals and SLAs using business process flows.
  • Fast time-to-value: Configure metadata, not custom code, to deliver quickly.

Step-by-Step: Build a Model-Driven App

  • 1. Plan your data model: Identify tables (e.g., Deals, Accounts), columns (e.g., Deal Value), and relationships.
  • 2. Create tables in Dataverse: Add columns, set data types, define relationships and choice fields.
  • 3. Design forms and views: Build main forms, quick create forms, and list views with relevant columns and filters.
  • 4. Add business rules and BPFs: Enforce field logic and create stage-based process guidance (Qualify → Propose → Close).
  • 5. Add charts and dashboards: Visualize KPIs like open deals, case backlogs, or SLA breaches.
  • 6. Secure the app: Configure security roles, field security profiles, and sharing as needed.
  • 7. Build the app shell: In Power Apps, create a model-driven app, add navigation areas, tables, views, and dashboards.
  • 8. Automate: Use Power Automate for notifications, approvals, and integrations (e.g., Teams, Outlook, SharePoint).
  • 9. Test and publish: Validate role-based experiences, performance, and data quality rules before rollout.

Real-World Examples

Sales Pipeline Management

Create tables for Leads, Opportunities, Products, and Quotes. Use a BPF to guide reps from Qualify to Close, automate quote approval with Power Automate, and surface a dashboard showing pipeline by stage and forecast category.

Customer Service Case Management

Use Cases, Queues, and SLAs. Route incoming cases based on topic and priority, track response times, and surface knowledge articles. Enable agents to update records via a streamlined model-driven interface.

Partner Onboarding Portal (with Power Pages)

Maintain Accounts and Partner Profiles in Dataverse. Expose selected data externally through Power Pages, while internal teams manage approvals and reviews in a model-driven app.

Key Benefits

  • Consistency: Standardized UI and validated data entry across teams.
  • Compliance-ready: Audit logs, security roles, and field-level security.
  • Scalable: Handles complex schemas and large user bases.
  • Low-code agility: Configure quickly, extend with pro-code when needed.

Best Practices and Governance

  • Solution-first development: Use managed/unmanaged solutions, publisher prefixes, and ALM pipelines.
  • Naming and schema discipline: Use consistent table/column naming and choice values.
  • Security by design: Define least-privilege roles early; avoid broad org-level permissions.
  • Data quality: Use required fields, duplicate detection, and business rules to enforce standards.
  • Performance: Optimize views, indexes, and avoid overly complex client scripts.
  • Documentation: Capture data model diagrams, process maps, and support playbooks.

FAQ

Is Dynamics CRM the same as Dynamics 365?

The term “Dynamics CRM” refers to the legacy branding. Today, capabilities are delivered through Dynamics 365 Customer Engagement apps (e.g., Sales, Customer Service) running on Dataverse.

Do I need Dynamics 365 to build a model-driven app?

No. You can build standalone model-driven apps on Dataverse. However, many organizations combine them with Dynamics 365 for richer, out-of-the-box capabilities.

Can I integrate with Outlook, Teams, or SharePoint?

Yes. Model-driven apps integrate with Microsoft 365, enabling email tracking, file storage, collaboration, and notifications.

Tuesday, 20 January 2026

typescript compatibility issue in spfx

Error :  typescript compatibility issue in spfx

Below is error  when runing  gulp build command after creating a new project or upgrading project.


E:\SharePointFrameWorkDEV\ReactSPFXSolution>gulp build
Build target: DEBUG
[12:22:17] Using gulpfile E:\SharePointFrameWorkDEV\ReactSPFXSolution\gulpfile.js
[12:22:17] Starting gulp
[12:22:17] Starting 'build'...
[12:22:17] Starting subtask 'configure-sp-build-rig'...
[12:22:17] Finished subtask 'configure-sp-build-rig' after 13 ms
[12:22:17] Starting subtask 'pre-copy'...
[12:22:17] Finished subtask 'pre-copy' after 56 ms
[12:22:17] Starting subtask 'copy-static-assets'...
[12:22:17] Starting subtask 'sass'...
[12:22:17] Finished subtask 'copy-static-assets' after 93 ms
[12:22:18] Finished subtask 'sass' after 615 ms
[12:22:18] Starting subtask 'tslint'...
[12:22:20] [tslint] tslint version: 5.12.1
[12:22:20] Starting subtask 'tsc'...

[12:22:20] [tsc] typescript version: 2.7.2

[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(34,39): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,47): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,48): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,49): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,76): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,100): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,103): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,119): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,144): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,152): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,160): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,50): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,51): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,52): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,69): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,71): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(53,30): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(53,54): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/prop-types/index.d.ts(53,57): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(56,51): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(57,17): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(58,25): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,21): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,29): error TS1131: Property or signature expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,35): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,41): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,55): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,63): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(107,67): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(108,5): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(316,50): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(316,72): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(316,75): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(715,15): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(715,29): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(717,13): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(717,16): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(721,15): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(721,29): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(722,17): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(722,31): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(722,39): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(723,17): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(723,26): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(724,42): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(724,71): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(725,21): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(726,17): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(727,13): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(727,16): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(736,11): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(736,47): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(737,13): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(738,17): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(738,31): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(742,11): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(742,40): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(743,13): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(743,34): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(744,13): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(744,46): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(786,56): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(786,78): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(786,86): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(787,57): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(787,84): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(787,87): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2653,31): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2655,13): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2655,25): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2657,13): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2658,5): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2658,6): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2687,33): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2687,41): error TS1131: Property or signature expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2688,28): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2688,38): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2689,5): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2728,1): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2732,32): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2732,43): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2732,71): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2732,73): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2732,80): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2737,45): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,17): error TS1005: ']' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,18): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,19): error TS1136: Property assignment expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,35): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,38): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,40): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2738,48): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2739,13): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2739,21): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2739,27): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2740,11): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2741,9): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2741,12): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2742,9): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2742,12): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2743,39): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2743,40): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2749,27): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2750,14): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2750,28): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2751,9): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2752,9): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2753,9): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2754,5): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2754,12): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2756,39): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2756,66): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2756,89): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2757,5): error TS1128: Declaration or statement expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2758,5): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2758,9): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2758,36): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2758,37): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2760,9): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2760,13): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2760,43): error TS1005: ',' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2760,44): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2762,13): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2762,16): error TS1005: ')' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2776,49): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2776,89): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2776,92): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2776,126): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2777,13): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2777,17): error TS1005: ':' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2777,57): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2777,60): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2777,94): error TS1005: ';' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2778,17): error TS1109: Expression expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2779,17): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2780,13): error TS1005: '(' expected.
[12:22:25] Error - [tsc] node_modules/@types/react/index.d.ts(2780,43): error TS1005: '(' expected.
[12:22:25] Error - 'tsc' sub task errored after 5.38 s
 exited with code 2
[12:22:25] 'build' errored after 7.85 s
[12:22:25]
[12:22:25] ==================[ Finished ]==================
Error - [tsc] node_modules/@types/prop-types/index.d.ts(34,39): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,47): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,48): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,49): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,76): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,100): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,103): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,119): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,144): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,152): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(36,160): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,50): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,51): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,52): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,69): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(38,71): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(53,30): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(53,54): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/prop-types/index.d.ts(53,57): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(56,51): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(57,17): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(58,25): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,21): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,29): error TS1131: Property or signature expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,35): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,41): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,55): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,63): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(107,67): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(108,5): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(316,50): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(316,72): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(316,75): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(715,15): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(715,29): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(717,13): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(717,16): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(721,15): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(721,29): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(722,17): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(722,31): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(722,39): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(723,17): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(723,26): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(724,42): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(724,71): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(725,21): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(726,17): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(727,13): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(727,16): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(736,11): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(736,47): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(737,13): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(738,17): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(738,31): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(742,11): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(742,40): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(743,13): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(743,34): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(744,13): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(744,46): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(786,56): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(786,78): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(786,86): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(787,57): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(787,84): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(787,87): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2653,31): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2655,13): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2655,25): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2657,13): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2658,5): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2658,6): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2687,33): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2687,41): error TS1131: Property or signature expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2688,28): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2688,38): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2689,5): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2728,1): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2732,32): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2732,43): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2732,71): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2732,73): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2732,80): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2737,45): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,17): error TS1005: ']' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,18): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,19): error TS1136: Property assignment expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,35): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,38): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,40): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2738,48): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2739,13): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2739,21): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2739,27): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2740,11): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2741,9): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2741,12): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2742,9): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2742,12): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2743,39): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2743,40): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2749,27): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2750,14): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2750,28): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2751,9): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2752,9): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2753,9): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2754,5): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2754,12): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2756,39): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2756,66): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2756,89): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2757,5): error TS1128: Declaration or statement expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2758,5): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2758,9): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2758,36): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2758,37): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2760,9): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2760,13): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2760,43): error TS1005: ',' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2760,44): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2762,13): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2762,16): error TS1005: ')' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2776,49): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2776,89): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2776,92): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2776,126): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2777,13): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2777,17): error TS1005: ':' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2777,57): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2777,60): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2777,94): error TS1005: ';' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2778,17): error TS1109: Expression expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2779,17): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2780,13): error TS1005: '(' expected.
Error - [tsc] node_modules/@types/react/index.d.ts(2780,43): error TS1005: '(' expected.
Error - 'tsc' sub task errored after 5.38 s
 exited with code 2
[12:22:26] Project student-details version:0.0.1
[12:22:26] Build tools version:3.12.1
[12:22:26] Node version:v10.14.2
[12:22:26] Total duration:15 s
[12:22:26] Task errors:138


Solution : 

1. First step to upgrade the rush stack compiler run "npm install @microsoft/rush-stack-compiler-3.2" command.
2.  open the "tsconfig.json"  and update the extend  property with the new rush stack compiler


Before 

"extends": "./node_modules/@microsoft/rush-stack-compiler-2.7/includes/tsconfig-web.json",


After update

"extends": "./node_modules/@microsoft/rush-stack-compiler-3.2/includes/tsconfig-web.json",

3. Close the file and run gulp build command 

this is the way to upgrade or downgrade the rush stack compiler in spfx

@hope problem will be resolved





Dataverse CRUD with a .NET 8 Console App using Managed Identity, DI, and Polly

Dataverse CRUD with a .NET 8 console app: this guide shows how to build a production-ready C# application that performs create, read, update, and delete operations against Microsoft Dataverse using Dependency Injection, DefaultAzureCredential, resilient retries (Polly), and clean configuration. You get copy-pasteable code, least-privilege security guidance, and optional Azure Container Apps + Key Vault deployment via azd/Bicep.

The Problem

You need a reliable way to run Dataverse CRUD from a console app without hardcoded secrets, avoiding static helpers, and ensuring the code is cloud-ready and testable. Many examples skip DI, retries, and security, leading to brittle apps.

Prerequisites

.NET 8 SDK, Azure CLI v2.58+, Azure Developer CLI (azd) v1.9+, Power Platform tooling access to create an Application User in Dataverse mapped to your app's Service Principal or Managed Identity, A Dataverse environment URL (e.g., https://yourorg.crm.dynamics.com)

The Solution (Step-by-Step)

1) Project setup and configuration

Create a new console app and add packages.

// Bash: create project and add packages
 dotnet new console -n DataverseCrud.Console --framework net8.0
 cd DataverseCrud.Console
 dotnet add package Microsoft.PowerPlatform.Dataverse.Client --version 1.1.27
 dotnet add package Azure.Identity --version 1.11.3
 dotnet add package Polly.Extensions.Http --version 3.0.0
 dotnet add package Microsoft.Extensions.Http.Polly --version 8.0.1

Add appsettings.json for configuration (no secrets).

{
  "Dataverse": {
    "OrganizationUrl": "https://yourorg.crm.dynamics.com",
    "ApiVersion": "v9.2", 
    "DefaultTableLogicalName": "account"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning"
    }
  }
}

Pro-Tip: Keep ApiVersion configurable so you can upgrade Dataverse API without code changes.

2) Implement the Generic Host with DI, typed options, and retry policies

Program.cs uses file-scoped namespaces, DI, and structured logging via Microsoft.Extensions.Logging. Polly adds resilient retries for transient failures.

using System.Net.Http.Headers;
using Azure.Core;
using Azure.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Polly;
using Polly.Extensions.Http;
using Microsoft.PowerPlatform.Dataverse.Client;

namespace DataverseCrud.ConsoleApp;

// Options record for strongly-typed config
public sealed record DataverseOptions(string OrganizationUrl, string ApiVersion, string DefaultTableLogicalName);

// Abstraction for testability
public interface IDataverseRepository
{
    // CRUD signatures using basic types for clarity
    Task<Guid> CreateAsync(string tableLogicalName, IDictionary<string, object> attributes, CancellationToken ct);
    Task<Dictionary<string, object>?> RetrieveAsync(string tableLogicalName, Guid id, string columnsCsv, CancellationToken ct);
    Task UpdateAsync(string tableLogicalName, Guid id, IDictionary<string, object> attributes, CancellationToken ct);
    Task DeleteAsync(string tableLogicalName, Guid id, CancellationToken ct);
}

// Concrete repository using ServiceClient
public sealed class DataverseRepository(IOptions<DataverseOptions> options, ILogger<DataverseRepository> logger, ServiceClient serviceClient) : IDataverseRepository
{
    private readonly DataverseOptions _opt = options.Value;
    private readonly ILogger<DataverseRepository> _logger = logger;
    private readonly ServiceClient _client = serviceClient;

    // Create a row in Dataverse
    public async Task<Guid> CreateAsync(string tableLogicalName, IDictionary<string, object> attributes, CancellationToken ct)
    {
        // Convert to Entity representation
        var entity = new Microsoft.Xrm.Sdk.Entity(tableLogicalName);
        foreach (var kvp in attributes)
            entity.Attributes[kvp.Key] = kvp.Value;

        var id = await _client.CreateAsync(entity, ct).ConfigureAwait(false);
        _logger.LogInformation("Created {Table} record with Id {Id}", tableLogicalName, id);
        return id;
    }

    // Retrieve a row with selected columns
    public async Task<Dictionary<string, object>?> RetrieveAsync(string tableLogicalName, Guid id, string columnsCsv, CancellationToken ct)
    {
        var columns = new Microsoft.Xrm.Sdk.Query.ColumnSet(columnsCsv.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries));
        var entity = await _client.RetrieveAsync(tableLogicalName, id, columns, ct).ConfigureAwait(false);
        if (entity == null)
        {
            _logger.LogWarning("Entity not found: {Table}/{Id}", tableLogicalName, id);
            return null;
        }
        return entity.Attributes.ToDictionary(k => k.Key, v => v.Value);
    }

    // Update specific attributes
    public async Task UpdateAsync(string tableLogicalName, Guid id, IDictionary<string, object> attributes, CancellationToken ct)
    {
        var entity = new Microsoft.Xrm.Sdk.Entity(tableLogicalName) { Id = id };
        foreach (var kvp in attributes)
            entity.Attributes[kvp.Key] = kvp.Value;

        await _client.UpdateAsync(entity, ct).ConfigureAwait(false);
        _logger.LogInformation("Updated {Table} record {Id}", tableLogicalName, id);
    }

    // Delete a row
    public async Task DeleteAsync(string tableLogicalName, Guid id, CancellationToken ct)
    {
        await _client.DeleteAsync(tableLogicalName, id, ct).ConfigureAwait(false);
        _logger.LogInformation("Deleted {Table} record {Id}", tableLogicalName, id);
    }
}

public class Program
{
    public static async Task Main(string[] args)
    {
        using var host = Host.CreateApplicationBuilder(args);

        // Bind options from configuration
        host.Services.AddOptions<DataverseOptions>()
            .Bind(host.Configuration.GetSection("Dataverse"))
            .ValidateDataAnnotations()
            .Validate(opt => !string.IsNullOrWhiteSpace(opt.OrganizationUrl) && !string.IsNullOrWhiteSpace(opt.ApiVersion));

        host.Services.AddLogging(builder =>
        {
            builder.AddSimpleConsole(o =>
            {
                o.TimestampFormat = "yyyy-MM-dd HH:mm:ss ";
                o.SingleLine = true;
            });
        });

        // Configure resilient HTTP with Polly for Dataverse traffic
        host.Services.AddHttpClient("dataverse")
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(GetRetryPolicy());

        // Register ServiceClient using DefaultAzureCredential (prefers Managed Identity in Azure)
        host.Services.AddSingleton(sp =>
        {
            var opts = sp.GetRequiredService<IOptions<DataverseOptions>>().Value;
            var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
            {
                // In production on Azure Container Apps/VMs, Managed Identity will be used.
                // Locally, DeveloperCredential/VisualStudioCredential will be used.
                ExcludeManagedIdentityCredential = false
            });

            var svc = new ServiceClient(new Uri(opts.OrganizationUrl), credential, useUniqueInstance: true, useWebApi: true);
            // Configure ServiceClient API version if supported/necessary by environment
            svc.SdkVersion = opts.ApiVersion; // Documented: keep version configurable
            return svc;
        });

        host.Services.AddSingleton<IDataverseRepository, DataverseRepository>();

        var app = host.Build();

        // Execute a CRUD flow
        var logger = app.Services.GetRequiredService<ILogger<Program>>();
        var repo = app.Services.GetRequiredService<IDataverseRepository>();
        var cfg = app.Services.GetRequiredService<IOptions<DataverseOptions>>().Value;

        using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2));

        try
        {
            // 1) Create
            var accountId = await repo.CreateAsync(cfg.DefaultTableLogicalName, new Dictionary<string, object>
            {
                ["name"] = "Contoso (Console App)",
                ["telephone1"] = "+1-425-555-0100"
            }, cts.Token);

            // 2) Retrieve
            var data = await repo.RetrieveAsync(cfg.DefaultTableLogicalName, accountId, "name,telephone1", cts.Token);
            logger.LogInformation("Retrieved: {Data}", string.Join("; ", data!.Select(kv => $"{kv.Key}={kv.Value}")));

            // 3) Update
            await repo.UpdateAsync(cfg.DefaultTableLogicalName, accountId, new Dictionary<string, object>
            {
                ["telephone1"] = "+1-425-555-0101"
            }, cts.Token);

            // 4) Delete
            await repo.DeleteAsync(cfg.DefaultTableLogicalName, accountId, cts.Token);

            logger.LogInformation("CRUD flow completed successfully.");
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Failure during CRUD flow");
            Environment.ExitCode = 1;
        }

        await app.StopAsync();
    }

    // Exponential backoff for transient HTTP 5xx/429 responses
    private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy() =>
        HttpPolicyExtensions
            .HandleTransientHttpError()
            .OrResult(r => (int)r.StatusCode == 429)
            .WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}

Pro-Tip: Add structured properties to logs (e.g., table, id) for easier querying in Application Insights.

3) Dataverse authentication without secrets

The ServiceClient uses DefaultAzureCredential, which in Azure will use Managed Identity. In local development, it falls back to developer credentials. You must create an Application User in Dataverse mapped to the Service Principal or Managed Identity and assign the least-privilege Dataverse security role needed for CRUD on targeted tables.

Pro-Tip: Scope Dataverse privileges to only the tables and operations your app requires.

4) Optional: Run in Azure Container Apps with Managed Identity (IaC via azd/Bicep)

If you want to run this console app on a schedule or on-demand in Azure, deploy to Azure Container Apps with a System-Assigned Managed Identity. Use Key Vault to hold non-secret config like OrganizationUrl and ApiVersion for central governance.

// azure.yaml for azd (simplified)
name: dataverse-crud
metadata:
  template: dataverse-crud
services:
  app:
    project: ./
    language: dotnet
    host: containerapp
    docker:
      path: ./Dockerfile
      context: ./

// main.bicep (simplified): Container App + Key Vault + MI and RBAC
param location string = resourceGroup().location
param appName string = 'dataverse-crud-app'
param kvName string = 'dvcrud-kv-${uniqueString(resourceGroup().id)}'

resource kv 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: kvName
  location: location
  properties: {
    tenantId: subscription().tenantId
    sku: { family: 'A', name: 'standard' }
    accessPolicies: [] // Use RBAC rather than access policies
    enableRbacAuthorization: true
  }
}

resource caEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
  name: 'dvcrud-env'
  location: location
}

resource app 'Microsoft.App/containerApps@2023-05-01' = {
  name: appName
  location: location
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    managedEnvironmentId: caEnv.id
    template: {
      containers: [
        {
          name: 'app'
          image: 'ghcr.io/yourrepo/dataverse-crud:latest'
          env: [
            // Pull configuration from Key Vault via secrets or set as plain env if non-secret
            { name: 'Dataverse__OrganizationUrl', value: 'https://yourorg.crm.dynamics.com' },
            { name: 'Dataverse__ApiVersion', value: 'v9.2' },
            { name: 'Dataverse__DefaultTableLogicalName', value: 'account' }
          ]
        }
      ]
    }
  }
}

// Grant the Container App's Managed Identity access to Key Vault secrets if used for configuration
resource kvAccess 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(kv.id, 'kv-secrets-user', app.name)
  scope: kv
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6') // Key Vault Secrets User
    principalId: app.identity.principalId
    principalType: 'ServicePrincipal'
  }
}

Azure RBAC roles used here: Key Vault Secrets User on the vault to read secrets if you store any configuration as secrets. The Container App requires no additional Azure RBAC to call Dataverse; it authenticates via its Managed Identity to Entra ID, and Dataverse access is governed by the Application User and Dataverse security role assignments.

Pro-Tip: Prefer System-Assigned Managed Identity for lifecycle simplicity unless you need identity reuse across apps, in which case use a User-Assigned Managed Identity.

5) Testing and mocking

Abstract your repository behind IDataverseRepository to unit test business logic without hitting Dataverse. For integration tests, use a test environment with a restricted Dataverse security role.

// Example unit test using a fake repository
public sealed class FakeRepo : IDataverseRepository
{
    public List<string> Calls { get; } = new();
    public Task<Guid> CreateAsync(string t, IDictionary<string, object> a, CancellationToken ct) { Calls.Add("create"); return Task.FromResult(Guid.NewGuid()); }
    public Task<Dictionary<string, object>?> RetrieveAsync(string t, Guid id, string cols, CancellationToken ct) { Calls.Add("retrieve"); return Task.FromResult<Dictionary<string, object>?>(new()); }
    public Task UpdateAsync(string t, Guid id, IDictionary<string, object> a, CancellationToken ct) { Calls.Add("update"); return Task.CompletedTask; }
    public Task DeleteAsync(string t, Guid id, CancellationToken ct) { Calls.Add("delete"); return Task.CompletedTask; }
}

Pro-Tip: Use dependency injection to pass a fake or mock implementation into services that depend on IDataverseRepository.

Best Practices & Security

Authentication and secrets: Use DefaultAzureCredential. Do not embed client secrets or connection strings. In Azure, rely on Managed Identity. Locally, authenticate via developer credentials.

Dataverse permissions: Assign a least-privilege Dataverse security role to the Application User (e.g., CRUD on specific tables only). Avoid granting environment-wide privileges.

Azure RBAC: If using Key Vault, grant only the Key Vault Secrets User role to the app’s Managed Identity. Do not grant Owner or Contributor without justification.

Resilience: The Polly retry policy handles 5xx/429 responses with exponential backoff; tune retry counts/timeouts per SLOs.

Observability: Use Microsoft.Extensions.Logging with structured state for IDs and table names. Forward logs to Application Insights via the built-in provider when running in Azure.

Configuration hygiene: Keep OrganizationUrl, ApiVersion, and default table logical names in configuration. Validate options at startup.

Token reuse: DefaultAzureCredential and underlying token providers cache tokens. Avoid recreating credentials per request; register ServiceClient as a singleton as shown.

Pro-Tip: For read-only operations at scale, prefer the Web API with select columns and server-side paging; avoid retrieving full records when not needed.

Summary

• You built a .NET 8 console app that performs Dataverse CRUD using DI, DefaultAzureCredential, and Polly retries.

• Security is hardened with Managed Identity, least-privilege Dataverse roles, and optional Azure RBAC for Key Vault.

• The solution is production-ready, testable, and configurable, with an optional path to deploy on Azure Container Apps via azd/Bicep.

Next step: map your Managed Identity or app registration to a Dataverse Application User, assign a minimal security role, and run the CRUD flow against your target tables.