Wednesday 5 August 2020

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. ]

Thursday 2 July 2020

EntityFramework Insert error due to PrimaryKey



MyProject.Controllers.CurrencyCodesController Unable to update the EntitySet 'CurrencyCodes' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
System.Data.Entity.Infrastructure.DbUpdateException: Unable to update the EntitySet 'CurrencyCodes' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation. ---> System.Data.Entity.Core.UpdateException: Unable to update the EntitySet 'CurrencyCodes' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.


Scenario: 
The error occured while trying to insert the currencycodes entity to the database. 
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "cucCurrencyCode,cucDescription,cucMultiplier,cucRate,cucInUse")] CurrencyCode currencyCode)
{ if (ModelState.IsValid)
{ try
{ db.CurrencyCodes.Add(currencyCode);
db.SaveChanges();
}
 catch (Exception ex) {
log.Error(ex.Message, ex);
}
 return RedirectToAction("Index");
} return View(currencyCode);

}



Solution: 
1) Check Primary key in .edmx file.  In my case cucInUse was set as Entity key. I removed it.
2) Now Right click the .edmx file and click "Open with...". Select XML (text) Editor
3)  Find the element <EntitySet name = "CurrencyCodes"...>
4) Change store:Schema="dbo" => Schema="dbo"
5) delete element <DefiningQuery>
6) Clean the project. 
7) close Visual studio.
8) Open visual studio. Open the project. 
9) Clean and build the project. 
10) Run the application.

Friday 26 June 2020

Fix for SSIS not picking correct configuration file

When there are more then one configuration file for a single package, the SSIS jobs sometimes do not automatically pick the correct configuration depending on how the settings has been made. 

In the SSIS package (using Visual Studio) Make sure you've done following correctly:
1) In the package property, Set Delay Validation =  false
2) Uncheck , Enable Package Configuration. 


steps for 2):
a) open the ssis package in visual studio.
b) In the Control flow tab, right click on the blank space of the canvas.
c) go to Package Configurations...
d) uncheck Enable Package Configuartion and press Close.
e) Save the ssis package and copy that to the deployed folder.

How to remove Workspace in TFS 2010-2018

This solution Works for TFS 2010+.

Open Visual studio Command prompt and run the following script.


tf workspace /delete /server:[Site:Port/path] WORKSPACENAME


for example:
tf workspace /delete /server:http://tfs.site.com:8080/tfs sanjeebPC

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>

Create XML from class or Object in C-Sharp

function to serialize object to xml in c#

public static string SerializeObjectToXML(object item)
        {
            try
            {
                string xmlText;
                Type objectType = item.GetType();
                XmlSerializer xmlSerializer = new XmlSerializer(objectType);
                MemoryStream memoryStream = new MemoryStream();
                using (XmlTextWriter xmlTextWriter =
                    new XmlTextWriter(memoryStream, Encoding.UTF8) { Formatting = Formatting.Indented })
                {
                    xmlSerializer.Serialize(xmlTextWriter, item);
                    memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                    xmlText = new UTF8Encoding().GetString(memoryStream.ToArray());
                    memoryStream.Dispose();
                    return xmlText;
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Write(e.ToString());
                return null;
            }
        }

Powershell script to create OS disk in azure from storage account blob image file (vhd)

Powershell script to create OS disk in azure from storage account blob image file (vhd)


#Provide the subscription Id where Managed Disks will be created
$subscriptionId = 'd7x2bxx8-62xe-4xdx-xa8x-20x0x3x2x5xx'

#Provide the name of your resource group where Managed Disks will be created. 
$resourceGroupName ='MYResourceGroupName'

#Provide the name of the Managed Disk
$diskName = 'Project_Disk2'

#Provide the size of the disks in GB. It should be greater than the VHD file size.
$diskSize = '90'

#Provide the storage type for Managed Disk. PremiumLRS or StandardLRS.
$storageType = 'Premium_LRS'

#Provide the Azure region (e.g. westus) where Managed Disk will be located.
#This location should be same as the storage account where VHD file is stored
#Get all the Azure location using command below:
#Get-AzLocation
$location = 'ukwest'

#Provide the URI of the VHD file (page blob) in a storage account. Please not that this is NOT the SAS URI of the storage container where VHD file is stored. 
#e.g. https://contosostorageaccount1.blob.core.windows.net/vhds/contosovhd123.vhd
#Note: VHD file can be deleted as soon as Managed Disk is created.
$sourceVHDURI = 'https://sanjeebojha.blob.core.windows.net/myproject/myoriginalVM.vhd'

#Provide the resource Id of the storage account where VHD file is stored.
#e.g. /subscriptions/6472s1g8-h217-446b-b509-314e17e1efb0/resourceGroups/MDDemo/providers/Microsoft.Storage/storageAccounts/contosostorageaccount
#This is an optional parameter if you are creating managed disk in the same subscription
$storageAccountId = '/subscriptions/d7x2bxx8-62xe-4xdx-xa8x-20x0x3x2x5xx/resourceGroups/MYResourceGroupName/providers/Microsoft.Storage/storageAccounts/sanjeebojha'

#Set the context to the subscription Id where Managed Disk will be created
Select-AzSubscription -SubscriptionId $SubscriptionId

$diskConfig = New-AzDiskConfig -AccountType $storageType -OsType Windows -Location $location -CreateOption Import -StorageAccountId $storageAccountId -SourceUri $sourceVHDURI 

New-AzDisk -Disk $diskConfig -ResourceGroupName $resourceGroupName -DiskName $diskName

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"/>

How to delete Local_lvm storage and resize local storage to use full disk space?

1) Delete the Local_lvm from othe proxmox interface . "datacenter" > Storage. Select the local_lvm storage and click "Remo...