Skip to main content Skip to footer

Migrating a WinForms Desktop App to ASP.NET MVC? How to Get Started

Migrating a WinForms App to ASP.NET MVC

If you have a WinForms app, there’s a good chance you’d like to modernize it by migrating it to an ASP.NET-based model-view-controller (MVC) architecture. Doing so can make it easier to extend the application or integrate it with new frameworks.

Undertaking a WinForms-to-ASP.NET MVC migration takes work. In this post, I'll explain the first key technical considerations when planning your migration.

In some cases, the desktop application cannot be extended because of desktop application limitations (such as an IoT integration). Independent of the reasons to migrate, some considerations need to be analyzed before starting the migration.

This article will discuss those considerations by highlighting the first items you should consider when migrating a WinForms app. Here are the following steps for getting started:

  1. Make sure migration is the best option
  2. Identify the platforms’ points of similarity
  3. Identify fundamental platform differences
  4. Identify code changes to migrate from WinForms to ASP.NET MVC
  5. Decide how to build a new interface using ASP.NET: interface and windowing considerations

Migrating to an ASP.NET MVC Architecture

1. The conceptual migration: Make sure migration is the best option

The first consideration is making sure that migrating to an ASP.NET MVC architecture is the right decision in the first place. In some scenarios, you could more easily modernize your app in other ways. For example, you could possibly containerize the application and share the access with a distributed team without rewriting. (As some developers say, the best code is the code we don't write.)

2. Identify the platforms’ points of similarity

If migration is the only option, we need to identify the points of similarity in the current technology in comparison to the new one. Of course, the migration from WinForms to ASP.NET MVC could be softer if the current application was developed with layers separating the logic in a similar construct to MVC. But we know that is almost impossible in most cases.

Although the concepts of WinForms and ASP.NET MVC differ, the classes could be the code most reused. Because of this, it should be a better starting point.

Many applications developed with WinForms have a persistent storage layer implemented inside the project including SQL code or a call to some procedures. Identify which your application is using, and after migrating the classes, start the migration of queries and functions from procedures.

3. Identify fundamental platform differences

The most challenging problem is the layer of viewers. Desktop applications involve many native events, and most could be migrated to events of the web page as mouse and keyboard events, but for other resources, such as the file manager, rethinking implementation is necessary.

Other aspects of migration will be the implementation of the controller, moving management of routes, and the logic of page redirects.

4. Identify code changes to migrate from WinForms to ASP.NET MVC

Now that we’ve discussed the considerations to keep in mind before starting the migration from WinForms to ASP.NET MVC, let’s take a look at what you should expect to change in your code in order to perform the migration.

As mentioned before, if you have SQL code in your project like the sample above, you can reuse the SQL in the query on the ASP.NET MVC project. Let's seek to understand this better by analyzing the code used to search users by country in the WinForms project.


// The SQL code to get users by country.
string sql = "SELECT * FROM Users WHERE countryID = @countryID";

// The connection treatment.
using (SqlCommand sqlCommand = new SqlCommand(sql, connection))
{
  // Inclusion of parameters to query.
  sqlCommand.Parameters.Add(new SqlParameter("@countryID", SqlDbType.Int));
  sqlCommand.Parameters["@countryID"].Value = countryID;

try

  {
    connection.Open();

    // Reader to get the users.
    using (SqlDataReader dr = sqlCommand.ExecuteReader())
    {
      DataTable dt = new DataTable();

      dt.Load(dr);

      // Attribute the data table to the data grid view shown on the screen.
      this.dgvUsers.DataSource = dt;

      dr.Close();
    }
  }
  catch
  {
    MessageBox.Show("ERROR");
  }
  finally
  {
    connection.Close();
  }
}

This code has SQL code, the treatment of the connection and the attribution of the result to the component used to show the list in the form. The communication with the database code and the view is strongly linked here. In addition, the treatment of errors starts a visual action showing an alert window.

Now, let's see the ASP.NET MVC code.


public async Task<ActionResult> UserDetail(int? countryID)
{
  // Verify if the parameter is valid, if not return the HTTP error.
  if (countryID == null)
  {
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  }

  // Find the users by countryID without using the SQL code.
  List<User> users = await db.Users.FindAsync(countryID);

  // Or search using the SQL query.
  string query = "SELECT * FROM Users WHERE countryID = @p0";
  List<User> users = await db.Users.SqlQuery(query, countryID).SingleOrDefaultAsync();

  // Verify if has some result, if not return the HTTP error.
  if (users == null)
  {
    return HttpNotFound();
  }

  // Send the list of users to view.
  return View(users);
}

This code uses two means to create a search. The first is from the Entity Framework and the second uses the raw SQL code that could facilitate the reuse of code from a WinForms project with significant amounts of raw SQL code. But the Entity Framework is preferred because of improved use of ASP.NET MVC resources.

In the view, we can loop the list of users and print the users in the CSHTML file:


<ul>
  @foreach (var user in users)
  {
    <li>
      @Html.ActionLink(user.Name)
    </li>
  }
</ul>

5. Decide how to build a new interface using ASP.NET: interface and windowing considerations

In addition to migrating the backend of your application, you also have to think about how to build a new interface using ASP.NET.

Fortunately, this is not as difficult as it may seem, even if you are not a frontend developer by trade. The MVC architecture approach makes it possible to use simple HTML and JavaScript for building an interface. That means that building an interface for your app after the migration requires only basic web development knowledge. Plus, JavaScript provides common events like click, hover and focus that are equivalent to those available from the WinForms, so it is easy to implement this same interface functionality after the migration.

Here's some sample code showing how you might approach crafting an interface after the migration without having to rearchitect your code to a significant extent. The only big difference in the example below in the interface before and after migration is that the web alert has no title on the prompt window.


// WinForms
Button alertButton = new Button();

alertButton.Click += new EventHandler(alertButton_Click);  

Controls.Add(alertButton);

void alertButton_Click(object sender, EventArgs e)
{
    MessageBox.Show("My message", "My title", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

// MVC
<button onclick="openAlert()">Open alert</button>

<script>
  function openAlert() {
    alert("My message");
  }
</script>

Migration Next Steps

WinForms has been in use for years, and ASP.NET MVC is a stable framework to build and migrate applications. What’s needed in a migration scenario is a deep knowledge of how the current application works and what can be done with it. Migration is difficult and slow; the work should be done with an enthusiastic team.

Additional things to consider:

  • Business intelligence conversion – C# WinForms to C# MVC or JavaScript
  • Discuss client-side to client-server events
  • Rest APIs
  • Cloud services – converting local storage to cloud data storage
  • Syntax differences

We will provide the next steps in a following article. In the meantime, if you have any questions, please leave them in the comment thread below.

Ready to Test it Out? Download ComponentOne Today!

comments powered by Disqus