Interview questions · free

.NET Developer interview questions and answers

24 questions .NET Developer interviews in India ask, grouped by the 5 skills they test, with a short model answer for each. Then the HR round every job has. Try each one out loud before you open the answer.

  • 24 questions
  • 5 skills
  • 13 for freshers
  • Updated 30 Oct 2026

First mock interview free: 3 questions, a score and feedback on each · No card needed

Answer out loud first. Read the question, say your answer as you would in the room, then open the model answer and compare. Interviewers ask follow-ups, so learn the reasoning, not the words.

C# · Core skill

OOP

.NET interviews start with C# itself: interviewers test whether you understand how types, inheritance and memory really work, because those decide how your code behaves.

What is the difference between a class and a struct in C#?Fresher

A class is a reference type: a variable holds a reference to an object on the heap, so assigning it to another variable copies the reference, and both point to the same object. Classes support inheritance and can be null. A struct is a value type: assigning it copies the whole value, and it's stored inline, for example on the stack as a local variable or inside the object that contains it. Structs can implement interfaces but can't inherit from another class or struct.

Use a struct for small values that behave like a single number, such as a point or a money amount, ideally immutable. Treating a struct as an object, for example through an interface, boxes it and adds a heap allocation.

What is the difference between a property and a public field in C#? Why do we usually use properties?Fresher

A field is a variable stored in the object. A property looks like a field to the caller but is a pair of get and set accessors. An auto-property like public string Name { get; set; } makes the compiler create a hidden backing field for you.

Properties let you change the inside later, adding validation or a computed value, without changing the code that uses the class. They allow different access levels, like a public get with a private set, or init so the value can be set only while creating the object. Interfaces can declare properties but not fields, and serialisers and data binding work with properties. So keep fields private and expose properties.

A method receives a List and assigns a new list to its parameter, but the caller's list doesn't change. If it calls Add(), the caller's list does change. Why?Fresher

In C#, arguments are passed by value by default. For a reference type like List, the value that's copied is the reference. So inside the method, the parameter and the caller's variable point to the same list: calling Add() changes that shared object, and the caller sees it. Assigning a new list changes only the method's local copy of the reference; the caller still points to the original.

If the method must replace the caller's variable, pass it with the ref keyword, or better, return the new list. Value types such as int or a struct are copied entirely, so changes inside never affect the caller. string is a reference type, but it's immutable, so it behaves like a value.

What is the difference between overriding a method with virtual and override, and hiding it with new?1-6 years

With virtual in the base class and override in the derived class, the method is chosen at runtime by the actual object: Base b = new Derived(); b.Show() runs Derived's Show. That's polymorphism. With new, the derived method only hides the base one; which runs depends on the variable's declared type, so b.Show() runs Base's version while a Derived variable runs Derived's. The compiler warns if you hide a method without writing new.

In practice, override is almost always what you want; hiding usually means a design problem or a base class you can't change. Related keywords: abstract forces derived classes to override, and sealed stops further overriding.

When would you use a record instead of a class in C#?1-6 years

Use a record when an object is defined by its data rather than its identity. Records, added in C# 9, give value-based equality: two records with the same property values are equal. A positional record such as public record Address(string City, string Pin); creates init-only properties, a constructor and a readable ToString(). A with expression makes a changed copy: var moved = address with { City = "Pune" }.

They suit DTOs, API requests and responses, messages and value objects like Money. They're usually a poor fit for Entity Framework entities, which have an identity and are tracked and changed in place. Since C# 10 there's also record struct for small value-type records.

ASP.NET Core · Core skill

Fundamentals

Every ASP.NET Core app is built on the same pipeline, routing, configuration and dependency injection, so interviewers check you understand what happens to a request from start to finish.

What is middleware in ASP.NET Core, and why does the order matter?Fresher

Middleware are the components that make up the request pipeline. Each one receives the request, can do some work, then either calls the next middleware or ends the request itself, and it sees the response on the way back out. They're added in Program.cs with app.Use... calls, and they run in exactly that order.

Order matters because each step depends on earlier ones. The exception handler goes first so it can catch errors from everything after it. Static files can return early without hitting authentication. UseRouting comes before UseAuthentication, which must come before UseAuthorization, otherwise authorization runs before the user is known and every protected request fails. You can write custom middleware for things like request logging or adding a correlation ID.

What is the difference between conventional routing and attribute routing?Fresher

Conventional routing defines URL patterns in one place, in Program.cs, for example app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"), so /Products/Details/5 maps to ProductsController's Details action. It suits MVC apps with server-rendered pages that follow a pattern.

Attribute routing puts the route on the controller and actions: [Route("api/orders")] on the class and [HttpGet("{id:int}")] on a method. It gives exact control over each URL and is the standard for Web APIs; [ApiController] requires it. Route constraints like :int or :guid stop a request from matching the wrong action. Both use endpoint routing underneath, so middleware such as authorization can see which endpoint was selected.

What is the difference between MVC and Razor Pages? When would you use each?Fresher

In MVC, a controller handles requests in action methods, prepares a model and chooses a view to render; controllers, models and views live in separate folders. In Razor Pages, each page is a .cshtml file with its own PageModel class holding handler methods such as OnGet and OnPost, and the URL follows the folder structure.

Razor Pages is simpler for page-focused apps, like admin screens and forms, because everything for a page sits together. MVC suits larger apps with many actions per area, shared logic across views, or a mix of pages and API endpoints. Both use the same Razor syntax, model binding, validation and tag helpers, and one project can use both.

How does configuration work in ASP.NET Core, and how do you keep a production connection string out of source code?1-6 years

The default builder reads several sources in order, and later ones override earlier ones: appsettings.json, then appsettings.{Environment}.json for the environment set by ASPNETCORE_ENVIRONMENT, then user secrets in Development, then environment variables, then command-line arguments. Sections map to environment variables with double underscores, so ConnectionStrings__Default overrides ConnectionStrings:Default.

So appsettings.json holds non-secret defaults, developers use user secrets locally, and production gets the connection string from an environment variable or a store like Azure Key Vault. Read settings through the options pattern: bind a section to a class with builder.Services.Configure and inject IOptions of that class, instead of reading strings everywhere.

What are the service lifetimes in ASP.NET Core dependency injection? What goes wrong if a singleton depends on a scoped service?1-6 years

Transient creates a new instance every time one is requested. Scoped creates one per request, shared by everything in that request. Singleton creates one for the whole application. DbContext is registered as scoped by default.

If a singleton takes a scoped service in its constructor, it keeps that one instance forever: a captive dependency. A DbContext captured this way is shared across requests and threads, isn't thread-safe, and keeps tracking entities until memory grows. In Development, ASP.NET Core validates scopes and throws at startup with "Cannot consume scoped service from singleton". Fix it by making the consumer scoped, or, in a singleton like a BackgroundService, inject IServiceScopeFactory and create a scope for each unit of work.

ASP.NET Core

Web APIs

Most .NET jobs today build Web APIs for web and mobile front ends, so interviewers ask how you bind, validate, document and secure them.

What does the [ApiController] attribute do?Fresher

It switches on API-friendly behaviour for a controller. The most useful: if model validation fails, it returns 400 Bad Request automatically with a ValidationProblemDetails body listing the errors, so you don't write if (!ModelState.IsValid) in every action. It also infers where parameters come from: complex types from the body, and route or query values for simple types, so [FromBody] is often unnecessary. It requires attribute routing, and turns error status codes into Problem Details responses.

Validation itself comes from data annotations on the model, such as [Required], [EmailAddress], [StringLength] and [Range], or from a library like FluentValidation. Controllers usually inherit from ControllerBase, not Controller, since an API doesn't need view support.

What is the difference between controllers and minimal APIs? When would you choose minimal APIs?1-6 years

Controllers group actions into classes, with attribute routing, filters and automatic model validation through [ApiController]; they suit large APIs with many endpoints and teams used to that structure. Minimal APIs map each endpoint directly to a handler in code: app.MapGet("/orders/{id}", (int id, IOrderService service) => ...). Dependencies are injected straight into the handler's parameters, and there's less ceremony and a little less overhead.

Minimal APIs suit small services and microservices, and they scale reasonably with MapGroup for shared prefixes and endpoint filters for cross-cutting work. Check how validation works in your .NET version before choosing. Both produce OpenAPI documents for Swagger, and both can live in one project.

How would you secure an ASP.NET Core Web API with JWT bearer tokens?1-6 years

Register authentication with AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(...), and either point it at your identity provider with Authority and Audience, such as Microsoft Entra ID, or set TokenValidationParameters to check the issuer, audience, lifetime and signing key. Add app.UseAuthentication() before app.UseAuthorization(), then protect endpoints with [Authorize], roles like [Authorize(Roles = "Admin")], or named policies for finer rules.

The API returns 401 when the token is missing or invalid and 403 when the user isn't allowed. Keep access tokens short-lived with refresh tokens, use HTTPS only, keep signing keys in a secret store, and add a bearer security definition to Swagger so testers can authorise there.

Data access

Entity Framework

Entity Framework Core is the default data layer in .NET projects, and interviewers check that you know what it does to your database, not just the syntax.

What is DbContext in Entity Framework Core, and what lifetime should it have in a web app?Fresher

DbContext is your session with the database. It exposes a DbSet for each entity, such as DbSet<Customer>, translates LINQ queries to SQL, and tracks the entities it loads. When you call SaveChanges(), it works out what changed and writes the inserts, updates and deletes in one transaction, so it acts as a unit of work.

In ASP.NET Core it's registered with AddDbContext, which gives it a scoped lifetime: one instance per request. That's deliberate, because a DbContext isn't thread-safe and its change tracker grows with every entity it sees. Never make it a singleton or share it across parallel tasks; for background work, create a new one per unit of work.

How do migrations work in Entity Framework Core, and how would you apply them in production?Fresher

With code-first, you change your entity classes, then run dotnet ef migrations add AddPhoneToCustomer. EF compares the model with its stored snapshot and generates a migration class with Up and Down methods. dotnet ef database update applies pending migrations, and the __EFMigrationsHistory table records which have run.

Always read the generated migration: a renamed property can appear as a dropped column and a new one, which loses data unless you fix it. For production, many teams generate a reviewed SQL script with dotnet ef migrations script --idempotent, or build a migration bundle and run it in the deployment pipeline, rather than calling Migrate() at startup on every instance.

A page listing orders with customer names is slow, and the logs show hundreds of SQL queries. What's happening, and how do you fix it in EF Core?1-6 years

That's the N+1 problem: one query loads the orders, then one more runs for each order's customer. In EF Core it usually means lazy loading is switched on (it's off by default) or the code queries inside a loop.

Fix it by loading what the page needs in one query. Include(o => o.Customer) adds a join. Better for a list page is a projection, Select(o => new OrderRow(o.Id, o.Total, o.Customer.Name)), which fetches only those columns. Add AsNoTracking() for read-only queries so EF doesn't track every entity. If you include several collections, AsSplitQuery() avoids one huge joined result. Check the generated SQL with logging before and after.

Reading an answer isn't the same as giving one

In a mock interview you answer new .NET Developer questions out loud or typed, and every answer is scored, with what to fix and a stronger answer.

Try it free

Data access

SQL Server

.NET applications in India very often run on SQL Server, and many teams still keep business logic in stored procedures, so expect T-SQL questions.

What is the difference between a stored procedure and a user-defined function in SQL Server?Fresher

A stored procedure is a saved batch of T-SQL that you run with EXEC. It can insert, update and delete data, manage transactions, return several result sets and use output parameters, but it can't be used inside a SELECT. A function returns a value (a scalar function) or a table (a table-valued function), and can be used inside SELECT, WHERE or JOIN, but it can't change data in database tables.

So use procedures for actions, like placing an order, and functions for reusable calculations or filtered row sets. Be careful with scalar functions in a WHERE clause on large tables: they can run once per row and be slow, while inline table-valued functions usually perform well.

What is the difference between a clustered and a non-clustered index?Fresher

A clustered index decides the order in which the table's rows are physically stored, so there can be only one per table. By default, creating a primary key creates it, unless the table already has one. A non-clustered index is a separate structure holding the indexed columns plus a pointer to the row, the clustered key, so a table can have many.

When a query needs columns that aren't in the non-clustered index, SQL Server does a key lookup for each row; adding them with INCLUDE makes a covering index and avoids that. A good clustered key is narrow, unique and ever-increasing, like an INT IDENTITY. A random GUID as the clustered key causes page splits and fragmentation, which is a common follow-up question.

How do you handle errors and transactions in a stored procedure so that a failure doesn't leave half-written data?1-6 years

Wrap the work in TRY and CATCH with an explicit transaction. Start with SET XACT_ABORT ON, so most runtime errors abort and roll back the whole transaction. Then BEGIN TRY, BEGIN TRANSACTION, do the inserts and updates, COMMIT TRANSACTION, END TRY. In BEGIN CATCH: IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION, log the error with ERROR_MESSAGE() and ERROR_NUMBER() if needed, and then THROW to send the original error back to the caller.

A common mistake is catching the error and carrying on silently, so the .NET code thinks it worked. Keep transactions short, and touch tables in the same order in every procedure to reduce deadlocks.

Every job

HR and behavioural round

.NET roles are often in service companies and client projects, so the HR round checks communication, flexibility about location and clients, and how you deliver under pressure.

Why did you choose .NET and C#?Fresher

Give reasons from your own experience, and show that you know where .NET is used. For example: "I started with C# in college and liked how clear and strongly typed it is. When I built [project] with ASP.NET Core and SQL Server, I found the tooling, Visual Studio, debugging and Entity Framework, made me productive quickly. .NET is used widely in enterprise, banking and healthcare systems, and it now runs on Linux and in containers too, so I see a long future in it."

Avoid saying you chose it by chance or only because the job was available. Show that you're open to front-end or cloud work alongside it.

Are you willing to relocate, or to work from a client's office?Fresher

Many .NET roles are on client projects, so the company needs to know where you can work. If you can, answer clearly and positively: "Yes, I'm open to relocating to [cities] or working from a client location. I see it as a chance to understand the client's business better." If you have a preference, say it as a preference, not a condition: "I'd prefer [city] because of family, but I'm flexible if the project needs it."

If you truly can't move, say so honestly now. It's better than accepting the offer and refusing a posting later.

Tell me about a time you had to meet a tight deadline. How did you manage it?1-6 years

Use STAR, and show that you planned and communicated, not just worked late. For example: "The client moved a release forward by a week (situation). I owned the reporting module (task). I listed the remaining work, agreed with the lead to deliver the three reports the client needed for launch and move the export feature to the next sprint, and told the client early. I also automated the test data setup, which saved a day (action). We released on time with no critical bugs, and the export followed a week later (result)."

Show that you protected quality and raised the risk early.

How do you work with a client or onsite team in a different time zone?1-6 years

Show that you make the overlap hours count and write things down well. For example: "In my last project the client was in [the UK], so we had about two overlapping hours. I prepared questions in advance, sent a short status update before their day started, and wrote clear tickets with screenshots and steps, so work didn't wait for a meeting. When something was urgent, I called instead of waiting for an email reply. I also adjusted my hours on release days."

Interviewers want to hear that you're proactive, communicate clearly in writing and stay flexible without being asked.

What is your notice period? Can you join earlier?1-6 years

Give the exact notice period from your contract and be honest about what's possible. For example: "My notice period is [60/90] days. I've discussed it with my manager, and I may be able to leave earlier once my current module is handed over. The company also allows a notice buyout, so we can discuss that if you need me sooner." If you've already resigned, give your last working day.

Don't promise an early date you can't keep: offers are sometimes withdrawn when a candidate can't join on the date they promised. Showing that you'll leave your current team in an orderly way reflects well on you.

Free interview questions, roadmaps and mock interviews: https://myskillgrid.com/interview-questions/dotnet-developer/

Ready to answer them for real?

Your first .NET Developer mock interview is free: 3 questions, a score and feedback for each, and a stronger answer to learn from, in about 10 minutes.