Showing posts with label .net. Show all posts
Showing posts with label .net. Show all posts

Saturday 11 September 2021

simple use of Record in c#9 and newer versions

 c# 9 introduces a new keyword Record which makes an object immutable. Properties in the record can be initialised at the time of creation or constructor call only. Record can be written like how we write a class. It has same syntax as class.

For example:

public record Friend

        {

            public Friend()

            {

            }

            public Friend(string name, string surname)

            {

                this.Name = name;

                this.Surname = surname;

            }

            public string Name { get; init; }

            public string Surname { get; init; }

        }

use of Friend record:

var newFriend = new Friend("Tom", "Pandey");

//--Note: we called here using constructor.

var newFriend1 = new Friend{Name="Tom",Surname= "Pandey"};

//Note: this calls the constructor without parameter. constructor without parameter is not required to to call to initiate the record. 

This record is equivalent to below code which don't have a constructor:

public record Friend

        {

            public string Name { get; init; }

            public string Surname { get; init; }

        }


use of Friend Record:

var newFriend = new Friend("Tom", "Pandey");

Note: we called here using constructor, but we don't have constructor defined. so It will throw an error. Instead we create object friend like this:

var newFriend1 = new Friend{Name="Tom",Surname= "Pandey"};

In both the example of Record, we can not modify the property Name or Surname after the object is created. 

The Friend record with constructor can be written as below code in one line:

public record Friend(String Name, String Surname);

use of Friend Record: 

Friend friend = new Friend("John","Pandey" );

Note: since this is constructor type record, we must create record object using constructor.for example below code will throw error:

var newFriend1 = new Friend{Name="Tom",Surname= "Pandey"};

On compilation, this is converted to class with immutable properties.

init only property in c#9 or later versions

 c# 9 introduces new Init-Only property that allow to make immutable properties in a class. This means the property with "init" keyword in place of "set" keyword allows the property to be initialized at the construction step of an object. it doesn't allow you to set the value later, once the object is initialised. 

For example

 public class Friend

        {

            public Friend(string name, string surname)

            {

                this.Name = name;

                this.Surname = surname;

            }

            public string Name { get; init; }


            public string Surname { get; init; }

        }


Use of Friend

   public void SomeMethod()

        {

            Friend friend = new Friend("John", "Sharma");

            var newFriend = new Friend("Tom", "Pandey");

        }

Use of init property after initialization throws an error. for eg.

 public void SomeMethod()

        {

            Friend friend = new Friend("John", "Sharma");

            var newFriend = new Friend("Tom", "Pandey");

            friend.Surname = "xxx"; //<--- Error here.

        }

Wednesday 5 August 2020

TFS -GIT CertGetCertificateChain trust error CERT_TRUST_IS_UNTRUSTED_ROOT


Problem 1)

2019-07-02T14:19:12.5157398Z fatal: unable to access 'https://tfssite.company.com/tfs/UK_ProjectCollection/SalesPortal/_git/SalesPortalWeb/': SSL certificate problem: unable to get local issuer certificate
2019-07-02T14:19:12.9764145Z ##[error]Git fetch failed with exit code: 128
2019-07-02T14:19:12.9861630Z ##[section]Finishing: Get Sources













In the TFS_Build Server or App server(if build and app server is in the same machine) >

run the script from this url: https://blog.sanjeebojha.com.np/2019/06/git-ssl-certificate-problem-unable-to.html

Once this is done, you should get another problem:

Problem 2)  CertGetCertificateChain trust error CERT_TRUST_IS_UNTRUSTED_ROOT

2019-07-02T14:24:57.1800199Z ##[command]git -c http.extraheader="AUTHORIZATION: bearer ***" fetch --tags --prune --progress --no-recurse-submodules origin
2019-07-02T14:24:57.4540146Z fatal: unable to access 'https://tfssite.company.com/tfs/UK_ProjectCollection/SalesPortal/_git/SalesPortalWeb/': schannel: CertGetCertificateChain trust error CERT_TRUST_IS_UNTRUSTED_ROOT
2019-07-02T14:24:57.5198064Z ##[error]Git fetch failed with exit code: 128

2019-07-02T14:24:57.5288511Z ##[section]Finishing: Get Sources


  











  1. Export the certificate public key to a file. The file is later required.
  2. Open the url "https://tfssite.company.com/tfs/projectcollection" in IE
  3. Click on the Lock icon in the browser address bar
  4. Select The Root level Certificate and Click View Certificate

Now Find the certificate file from GIT folder. 
normally it's inside GIT\usr\ssl\certs folder

  1. Copy the file to User folder
copy ca-bundle.trust.crt c:\Users\svc_tfs17_app

  1. Config Git to use trusted certificate using the crt file.  
    git config --global http.sslCAInfo c:\Users\svc_tfs17_app\ca-bundle.crt
  2. Convert the \n (Unix) to \r\n (Windows) so that it can be displayed by notepad editor correctly.
  3. Use the unix2dos open source software to convert \n to \r\n, or other notepad editor to replace \n to \r\n.
  1. Copy the content of tfs.cer from step o to ca-bundle.crt at the bottom of the file.

Done!

Output :


Read TFS Project name from TFS Project collection using c#


Using Team foundation api.
 References:
Capture.PNG
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.dll
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Client.dll
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Common.dll
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.WorkItemTracking.Client.dll


Code:
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using System;
using System.Linq;

class Program
{ private static ICommonStructureService _commonStructureService;
static void Main(string[] args)
{
ReadProject("https://tfssite.com/tfs/UK_ProjectCollection");
ReadProject("https://tfssite.com/tfs/IN_ProjectCollection");
Console.ReadKey();
}
 public static void ReadProject(String URL)
{
writeFile("Project Collection: " + URL);
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(URL));
var collection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tpc.Uri);
_commonStructureService = collection.GetService<ICommonStructureService>(); var projects = _commonStructureService.ListAllProjects().OrderBy(a => a.Name);
foreach (var project in projects)
{

writeFile(project.Name);
}
 writeFile("------------------------------------------------------------------------------");
} public static void writeFile(String message) {
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(@"C:\temp\tfs.txt"true))
{
file.WriteLine(message);
}
}
}

Output is the list of project names in tfs.txt file. 

GIT - SSL certificate problem: unable to get local issuer certificate

Error encountered while cloning the remote repository: Git failed with a fatal error.
unable to access 'https://tfssite.company.com/tfs/uk_projectcollection/SalesPortal/_git/SalesPortalWeb/': SSL certificate problem: unable to get local issuer certificate

Cloning into 'C:\Users\sojha\Source\Repos\SalesPortalWeb'...
Error encountered while cloning the remote repository: Git failed with a fatal error.
unable to access 'https://tfssite.company.com/tfs/uk_projectcollection/SalesPortal/_git/SalesPortalWeb/': SSL certificate problem: unable to get local issuer certificate




Solution: Open Visual Studio Command prompt

GIT provides an option to choose from OpenSSL and Secure Channel. Choosing secure channel in git global solves this issue.

Run the script:

git config --global http.sslBackend schannel

Entity Framework Core with Existing Database

Entity Framework Core only supports code first database aproach. 
To use existing database, we'll need to reverse Engineer Model from existing Database. 
  • Open Visual studio.
  • Menu > tools >Nuget Package Manager >
  • open PM Console
Note: All the tables in the database must have Primary key defined. else you'll get error like:
Unable to generate entity type for table 'dbo.xOrdersMBS'.
Unable to identify the primary key for table 'dbo.xActivePricesEPB'.
Unable to generate entity type for table 'dbo.xActivePricesEPB'.
Unable to identify the primary key for table 'dbo.xLeadTimePBOM'.
Unable to generate entity type for table 'dbo.xLeadTimePBOM'.


 In the console, run the below power shell commands:

Using Windows Authentication:
Scaffold-DbContext "Server=DatabaseServerAddress;Database=DatabaseName;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -f

Using SQL Account:
Scaffold-DbContext "data source=DatabaseServerAddress;initial catalog=DatabaseName;uid=UserName;pwd=Password;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -f

Note: -f force create the files if the file exist in the folder Models.

Thursday 16 July 2020

Add nuget packages to Artifacts in Azure devops

download latest nuget.exe from the nuget site. (google it)

copy the nuget.exe in d: (any location is fine)

Use visual studio -> Package manager console. 
run the below command
D:\nuget.exe push -Source "IGTelerikFeed" -ApiKey az D:\Telerik.UI.for.AspNet.Core.2020.2.617.nupkg

[Note: It will ask Credential to connect to the devops when you press enter. ]

Friday 26 June 2020

Use log4net for all logging in c# application

Exception logging is hugely important within an application, not just to ensure we know when an error has occured but also to help use trace back the thread to help investigate where the error originated.
Our strategy is to use log4net for all our logging needs.
This page helps cover the follow areas
1. Setting up logging across the entire applications
2. Including 2 appenders so we can be notified when they occur and ensure a tracable debug log file is available.
Setting up your Applications for Logging
Reference log4net in your applications
in Global.asax under the start_application method include the following
    void Application_Start(object sender, EventArgs e)
    {
        // link up log4net configuration
        log4net.Config.XmlConfigurator.Configure();
    }
On the page where you wish to log information declare a new static variable in the class header
log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Whenever you wish to now log an event in this class run one of the follow commands, ensure you include the exception when needed
log.Error("An unhandled exception occured", ex);
To ensure you catch all unhandled exceptions include the following in your Global.asax file. Remember to declare the log variable in the class too.
    void Application_Error(object sender, EventArgs e) 
    {
        // Code that runs when an unhandled error occurs
        // get last exception
        Exception ex = Server.GetLastError().GetBaseException();
        // log it
        log.Error("An unhandled exception occured", ex);
    }
Web.Config Settings
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
<log4net>
    <!-- The DebugFileAppender writes all messages to a log file-->
    <appender name="DebugFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="L:\[APPNAME]\Log.txt" /> <!-- These should be located on the "L" drive (if available) and stored under a folder named for the specific application -->      <datePattern value="'ApplicationLog.'yyyy-MM-dd'.txt'" />
      <staticLogFileName value="false" />
      <rollingStyle value="Composite" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="5MB" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d [%t] %-5p %c %m%n" />
      </layout>
    </appender>    <!-- The EmailAppender sends an email when something matches the filters-->
    <appender name="EmailAppender" type="log4net.Appender.SmtpAppender">
      <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="DEBUG"/>
      </evaluator>
      <!--  The filters are processed in order:
            1) match the Inserted New User message
            2) match any WARN or higher messages
            3) reject everything else -->
      <filter type="log4net.Filter.StringMatchFilter">
        <stringToMatch value="Inserted a new user" />
        <acceptOnMatch value="true" />
      </filter>
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="WARN" />
        <acceptOnMatch value="true" />
      </filter>
      <filter type="log4net.Filter.DenyAllFilter" />
      <!--  The SmtpAppender authenticates against the mail server, the buffersize of 10 provides 10 lines
            of context when an error happens. -->
      <subject value="[SEVERITY] [ENV] [APPNAME] - [EXCP_MSG]" />
      <to value="itteam@site.com" />
      <from value="noreply@site.com" />
      <smtpHost value="smtpmail.lu.sii.com" />
      <bufferSize value="10" />
      <lossy value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
      </layout>
    </appender>
    <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
      <applicationName value="MyApp" />


     <layout type="log4net.Layout.PatternLayout">


        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />


      </layout>


    </appender>

    <root>
      <!-- add other appenders here and the log messages will be sent to every listed appender -->
      <appender-ref ref="DebugFileAppender" />
      <appender-ref ref="EmailAppender" />
    </root>
  </log4net>

Solution to the CORS issue

CORS:Cross-Origin Resource Sharing

In the web.config file, add the following:


<system.webServer>
   <httpProtocol>
     <customHeaders>
        <add name="access-control-allow-origin" value="*" />
        <add name="access-control-allow-headers" value="content-type" />
     </customHeaders>
   </httpProtocol>
</system.webServer>  
Enable anonymous authentication 
    <anonymousAuthentication enabled="true"/>

Generate SQL script from entity framework using powershell/visual studio

to run the below command , start PowerShell in visual studio. Select the database project. In PowerShell:   Script-Migration this command wi...