A Strategic Roadmap for a Distributed Workforce

About This Document

Curious about using ChatGPT to migrate your code? The Programmer’s Guide to Using ChatGPT to Migrate Code takes you through the process of transforming a VB.NET WinForms application into a modern C#/Blazor web app. This guide highlights the successes and challenges faced, the benefits of using ChatGPT, and crucial tips for a successful migration. Understand how AI tools can aid in modernizing your applications while collaborating with developers to achieve the best results.

Full Content Below

Read the Full Document

Explore the complete publication below

We’ve all asked ourselves the same question: can generative AI migrate an old legacy application? The answer is “yes,” but there are a lot of caveats.

In this post, we’ll share our experiences and learnings from using ChatGPT 4.0 to migrate a legacy VB.NET Winforms application to a modern C#/Blazor web application. The project aimed to use the power of generative AI’s natural language processing and code generation capabilities to streamline the migration process.

Humorous meme depicting a figure labeled My Code being chased by a figure labeled ChatGPT Migrating My Code in a school hallway

Tech Specs

The source application was a .NET 4.8/Entity Framework 6.4.4 VB.NET WinForms app developed in Visual Studio 2022. The target application was .NET 8/Entity Framework Core 8.0.2 C#/Blazor Server web app, also in VS2022.

What We Learned

Form Mapping and Understanding

Translating VB.NET WinForms to a Blazor web app required more than just code conversion. It involved understanding the structure, features and complexities of the source application, defining the scope of the migration and planning the architecture of the target Blazor application.

Migration Approach

We approached the migration in these phases:

  • Analyzing and planning
  • Setting up the Blazor project
  • Migrating business logic
  • Developing the UI with Blazor components
  • Handling data access and state management
  • Implementing authentication and authorization
  • Testing and deployment
  • Training and documentation

Factoring the Application

The VB.NET application lacked proper separation of concerns, with business logic and data access mixed in the UI layer. For an effective migration, it was crucial to refactor the application into distinct layers – UI, business logic and data access.

Iterative Migration and Learning Curve

The migration was an iterative process, requiring frequent adjustments and learning. As we gained more understanding of Blazor and .NET 8, the code generated by ChatGPT needed to be fine-tuned. The learning curve involved adapting to new concepts and best practices in C#, Blazor and Entity Framework Core.

Areas Where ChatGPT Exceeded Expectations

Code Translation:

ChatGPT (and generative AI in general) demonstrated impressive capabilities in translating VB.NET code to C#, handling complex constructs and providing syntactically correct code. Here are a few examples:

Business Logic Migration

Before (VB.NET):

Public Function Login(userid As String, password As String) As AccountCurrent
    Dim theAccount As New AccountCurrent
    theAccount.UserID = userid
    Using accountcontext As New ACCOUNTDBEntities()
        Dim parameter = New SqlParameter("@userId", userid)
        Dim result = accountcontext.ACCOUNTPROFILEs.SqlQuery("SELECT * FROM
dbo.ACCOUNTPROFILE WHERE USERID = @userId", parameter)
        For Each profile In result
            theAccount.UserID = profile.USERID
            theAccount.Password = profile.PASSWORD
            theAccount.AccountID = profile.ACCOUNTID
            theAccount.Salt = profile.SALT
            theAccount.Name = profile.FULLNAME
        Next
        If theAccount.Password Is Nothing Then
            GlobalSettings.LoggedIn = False
        Else
            Dim ver = New SaltedHash().Create(theAccount.Salt,
            theAccount.Password)
            GlobalSettings.LoggedIn = ver.Verify(password)
        End If
    End Using
    Return theAccount
End Function

After (C#)

public async Task<AccountCurrent> LoginAsync(string userId, string password)
{
    var theAccount = new AccountCurrent();
    using (var accountContext = new ACCOUNTDBEntities())
    {
        var parameter = new SqlParameter("@userId", userId);
        var accountProfiles = await accountContext.ACCOUNTPROFILEs
            .FromSqlRaw("SELECT * FROM dbo.ACCOUNTPROFILE WHERE USERID = @userId", parameter)
            .ToListAsync();
        foreach (var profile in accountProfiles)
        {
            theAccount.UserID = profile.UserId;
            theAccount.Password = profile.Password;
            theAccount.AccountID = profile.AccountId;
            theAccount.Salt = profile.Salt;
            theAccount.Name = profile.FullName;
        }
        if (theAccount.Password == null)
        {
            GlobalSettings.LoggedIn = false;
        }
        else
        {
            var verifier = SaltedHash.Create(theAccount.Salt, theAccount.Password);
            GlobalSettings.LoggedIn = verifier.Verify(password);
        }
    }
    return theAccount;
}

UI Migration

Before (VB.NET)

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    GlobalSettings.LoggedIn = False
End Sub

Private Sub Label3_Click(sender As Object, e As EventArgs) Handles Label3.Click
    Form1.Show()
End Sub

Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
    If GlobalSettings.LoggedIn Then
        MsgBox("You are now Logged Out!")
        GlobalSettings.LoggedIn = False
        Login.PasswordTextBox.Text =""
        Login.UserIDTextBox.Text =""
    Else
        Login.Show()
    End If
End Sub

After (Blazor):

@page "/"
@inject NavigationManager NavigationManager
@inject IAuthenticationService AuthenticationService

<h3>Welcome</h3>

@if (!AuthenticationService.IsLoggedIn)
{
    <p>Please log in to continue.</p>
}
else
{
    <div>
        <button @onclick="NavigateToForm1">Go to Form 1</button>
        <button @onclick="ToggleLogin">Toggle Login</button>
        <button @onclick="NavigateToHoldings">Holdings</button>
        <button @onclick="NavigateToAccountForm">Account</button>
    </div>
}

@code {
    private void NavigateToForm1()
    {
        NavigationManager.NavigateTo("/form1");
    }

    private void ToggleLogin()
    {
        if (AuthenticationService.IsLoggedIn)
        {
            AuthenticationService.Logout();
        }
        else
        {
            NavigationManager.NavigateTo("/login");
        }
    }

    private void NavigateToHoldings()
    {
        if (AuthenticationService.IsLoggedIn)
        {
            NavigationManager.NavigateTo("/holdings");
        }
        else
        {
            // Show a message or modal indicating the need to log in
        }
    }

    private void NavigateToAccountForm()
    {
        if (AuthenticationService.IsLoggedIn)
        {
            NavigationManager.NavigateTo("/account");
        }
        else
        {
            // Show a message or modal indicating the need to log in
        }
    }
}

These examples show how ChatGPT translated the code from VB.NET to C#, handling differences in syntax, control flow and UI paradigms.

Best Practices:

  • Identifying best practices: ChatGPT often suggested best practices and modern approaches, such as using async/await, dependency injection and separating concerns, even when the source code didn’t follow these patterns.
  • Providing explanations: Along with generating code, ChatGPT offered clear explanations and reasoning behind its suggestions, helping us understand the rationale and learn new concepts.
  • Handling different target platforms: ChatGPT was able to generate code targeting different platforms including Node.js/Angular, showcasing its versatility.
  • Database class generation: Effective creation of database models from DDL.
  • Debugging support: Played a significant role in resolving code issues.

Want to Learn More?

Read the complete guide on Issuu.

Read Publication

Limitations of Generative AI

While ChatGPT was helpful in generating code snippets and providing guidance, it had limitations. The generated code often needed manual adjustments to align with the latest .NET versions and Blazor best practices.

Here are a few examples we encountered:

Entity Framework Core Usage:

ChatGPT generated the following code for querying the database using Entity Framework Core:

var result = _accountContext.ACCOUNTPROFILEs.SqlQuery("SELECT * FROM dbo.ACCOUNTPROFILE WHERE USERID = @userId", parameter);

However, this code uses the SqlQuery method, which is not available in Entity Framework Core. The code needed to be manually adjusted to use the FromSqlRaw method instead:

var accountProfiles = _accountContext.ACCOUNTPROFILEs
    .FromSqlRaw("SELECT * FROM dbo.ACCOUNTPROFILE WHERE USERID = @userId", parameter)
    .ToList();

Asynchronous Code:

ChatGPT sometimes generated synchronous code, even when as