C-Sharp Archives - KarthikTechBlog https://karthiktechblog.com/category/c-sharp/ Everyone can code! Sun, 18 Oct 2020 00:30:48 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.2 https://karthiktechblog.com/wp-content/uploads/2022/08/cropped-lsc-logo-png-new-3-32x32.png C-Sharp Archives - KarthikTechBlog https://karthiktechblog.com/category/c-sharp/ 32 32 How to resolve Cannot access a disposed object in Dotnet Core when injecting DbContext https://karthiktechblog.com/c-sharp/how-to-resolve-cannot-access-a-disposed-object-in-dotnet-core-when-injecting-dbcontext/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-resolve-cannot-access-a-disposed-object-in-dotnet-core-when-injecting-dbcontext https://karthiktechblog.com/c-sharp/how-to-resolve-cannot-access-a-disposed-object-in-dotnet-core-when-injecting-dbcontext/#respond Sun, 18 Oct 2020 00:30:48 +0000 https://karthiktechblog.com/?p=725 Accessing DbContext after it is disposed will cause a “Cannot access a disposed object in dotnet Core when injecting DbContext” error. Entity Framework (EF) Core is a lightweight, open-source. EF Core can serve as an object-relational mapper (O/RM). A DbContext instance represents a session with the database and can be used to query and save […]

The post How to resolve Cannot access a disposed object in Dotnet Core when injecting DbContext appeared first on KarthikTechBlog.

]]>
Accessing DbContext after it is disposed will cause a “Cannot access a disposed object in dotnet Core when injecting DbContext” error.

Entity Framework (EF) Core is a lightweight, open-source. EF Core can serve as an object-relational mapper (O/RM). A DbContext instance represents a session with the database and can be used to query and save instances of your entities.

DbContext is a combination of the Unit Of Work and Repository patterns and it is not thread-safe.

DbContext should not be accessed by multiple threads at the same time. In the dot net core, there are different possibilities of getting this error.

Possibility of getting Cannot access a disposed object error

When DbContext is used by multiple threads, one thread opens the connection to execute the query, and meanwhile, the second thread might have executed its query and closes the connection.

When this happens, the first thread throws an error that the DbContext is disposed. Avoid using multithreading with DbContext. Read more on working with DbContext

In dot net core, we have three service lifetime. Most of the time, DbContext is configured to be scoped service.

  • Transient
  • Scoped
  • Singleton

When an http request is served and returned with response, if you access DbContext service instance in any of the background work, then you will get this error.

Refer to this post for more details on how to Implement background tasks using IHostedService and access scoped service using IServiceScopeFactory

How to access scoped service using IServiceScopeFactory

Inject IServiceScopeFactory in the constructor and using this service you can get scoped service as described below.

        private readonly ILogger<StatusCheckerService> logger; 
	private readonly IServiceScopeFactory serviceScopeFactory;

        public StatusCheckerService(
            ILogger<StatusCheckerService> logger,IServiceScopeFactory serviceScopeFactory)
        {          
            this.logger = logger;
            this.serviceScopeFactory = serviceScopeFactory;
        } 

//In the method where you need scoped service, use below.

using (var scope = serviceScopeFactory.CreateScope())
                {
	// You can ask for any service here and DI will resolve it and give you back service instance
var contextService = scope.ServiceProvider.GetRequiredService<IContextService&ht;(); 
				   contextService.YourMethodOrServiceMethod(); //access dbcontext or anything thats available form your service
	}

Related Posts

Conclusion

In this post, I showed how to avoid Cannot access a disposed object in dotnet Core when injecting DbContext error. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below

The post How to resolve Cannot access a disposed object in Dotnet Core when injecting DbContext appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/c-sharp/how-to-resolve-cannot-access-a-disposed-object-in-dotnet-core-when-injecting-dbcontext/feed/ 0 725
Implementing custom validation using IValidatableObject https://karthiktechblog.com/c-sharp/implementing-custom-validation-using-ivalidatableobject-in-asp-dotnet-core/?utm_source=rss&utm_medium=rss&utm_campaign=implementing-custom-validation-using-ivalidatableobject-in-asp-dotnet-core https://karthiktechblog.com/c-sharp/implementing-custom-validation-using-ivalidatableobject-in-asp-dotnet-core/#respond Thu, 11 Jun 2020 15:50:29 +0000 https://karthiktechblog.com/?p=515 I recently started Implementing custom validation using IValidatableObject in my DOT NET CORE application. We often use data annotation for simple validation for the properties in our model class. I was wondering how to validate a particular property against some data in the database. I’m happy to know that IValidatableObject can be used to do […]

The post Implementing custom validation using IValidatableObject appeared first on KarthikTechBlog.

]]>
I recently started Implementing custom validation using IValidatableObject in my DOT NET CORE application.

We often use data annotation for simple validation for the properties in our model class. I was wondering how to validate a particular property against some data in the database. I’m happy to know that IValidatableObject can be used to do any sort of validation.

In this post, I’m going to show how to make use of IValidatableObject to validate a property for different scenarios.

I have used DOT NET CORE Web API for this demo.

I have created a folder named, Validation and created an abstract class named AbstractValidatableObject. This class inherits IValidatableObject class and we can implement a common logic to asyn and async Validate methods as shown below.

public abstract class AbstractValidatableObject : IValidatableObject
    {

        public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            CancellationTokenSource source = new CancellationTokenSource();

            var task = ValidateAsync(validationContext, source.Token);

            Task.WaitAll(task);

            return task.Result;
        }

        public virtual Task<IEnumerable<ValidationResult>> ValidateAsync(ValidationContext validationContext, CancellationToken cancellation)
        {
            return Task.FromResult((IEnumerable<ValidationResult>)new List<ValidationResult>());
        }
    }

IValidatableObject Interface provides a way for an object to be invalidated.

It has a method named Validate(ValidationContext) that determines whether the specified object is valid.

Parameters

validationContextValidationContext – The validation context.

Returns

IEnumerable<ValidationResult> – A collection that holds failed-validation information.

For demonstration purposes, I have created a Model class named Employee and a service for Employee.

Model

public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
        public decimal Salary { get; set; }
        public int Age { get; set; }
   }

Implementing Service

using System.Threading.Tasks;

namespace ArticlesDemo.Service
{
    public interface IEmployeeService
    {
        Task IsEmployeeExist(int employeeId);
    }
}

using System.Threading.Tasks;

namespace ArticlesDemo.Service
{
    public class EmployeeService : IEmployeeService
    {
        public async Task IsEmployeeExist(int employeeId)
        {
            await Task.Delay(1000);
            if (employeeId > 1000 && employeeId < 1500)
                return true;
            else
                return false;
        }
    }
}

Implementing custom validation using IValidatableObject

I want to use different validation for Employee model class that can be validated whenever it was used.

I have four properties in this model, I'm using data annotation for Name property. The other three properties are validated in the ValidateAsync method which is from IValidatableObject Interface.

using ArticlesDemo.Service;
using ArticlesDemo.Validation;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Threading.Tasks;

namespace ArticlesDemo.Model
{
    public class Employee : AbstractValidatableObject
    {
        public int EmployeeId { get; set; }

        [MinLength(2, ErrorMessage = "Minimum 2 characters required"), MaxLength(50, ErrorMessage = "Maximum 50 characters allowed")]
        public string Name { get; set; }
        public decimal Salary { get; set; }
        public int Age { get; set; }


        public override async Task<IEnumerable<ValidationResult>> ValidateAsync(ValidationContext validationContext,
         CancellationToken cancellation)
        {
            var errors = new List<ValidationResult>();
           

            if (Salary < 10000)
                errors.Add(new ValidationResult("Salary cannot be less than $10,000", new[] { nameof(Salary) }));

            if (Age < 18)
                errors.Add(new ValidationResult($"Age: {Age} not allowed to work. Minimum age is 18 or more", new[] { nameof(Age) }));

            //get the required service injected
            var dbContext = validationContext.GetService<IEmployeeService>();

            // Database call through service for validation
            var isExist = await dbContext.IsEmployeeExist(EmployeeId);
            if (isExist)
            {
                errors.Add(new ValidationResult("EmployeeId exist", new[] { nameof(EmployeeId) }));
            }

            return errors;
        }
    }
}

As you have seen, there was a method in the IEmployeeService to check whether a given employee id exist in the system or not. We can even inject any service and validate the data against database as part of our validation.

Don't forget to add the IEmployeeService in the Startup class.

Startup Class

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddScoped<IEmployeeService, EmployeeService>();
        }

Output Validation Message

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|87776fa6-4a037412bfcb49c8.",
    "errors": {
        "Age": [
            "Age: 17 not allowed to work. Minimum age is 18 or more"
        ],
        "Salary": [
            "Salary cannot be less than $10,000"
        ],
        "EmployeeId": [
            "EmployeeId exist"
        ]
    }
}

You may now use this errors property in the UI and show appropriate validation message.

Implementing custom validation using IValidatableObject
Implementing custom validation using IValidatableObject

Advantage of using this approach

There is one good advantage for using this approach in ASP NET CORE application. The call lands inside the controller's action method only when the validation is success.

Related Post

Conclusion

In this post, I showed Implementing custom validation using IValidatableObject in ASP.NET Core. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post Implementing custom validation using IValidatableObject appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/c-sharp/implementing-custom-validation-using-ivalidatableobject-in-asp-dotnet-core/feed/ 0 515
This project references NuGet package(s) that are missing on this computer. https://karthiktechblog.com/c-sharp/this-project-references-nuget-package-that-are-missing-error/?utm_source=rss&utm_medium=rss&utm_campaign=this-project-references-nuget-package-that-are-missing-error https://karthiktechblog.com/c-sharp/this-project-references-nuget-package-that-are-missing-error/#respond Thu, 16 Apr 2020 02:49:09 +0000 https://karthiktechblog.com/?p=463 Many of us have ran into issue “This project references NuGet package(s) that are missing on this computer”. There are many different reason as to why someone will get this error while you build the solution. Error Details This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download […]

The post This project references NuGet package(s) that are missing on this computer. appeared first on KarthikTechBlog.

]]>
Many of us have ran into issue “This project references NuGet package(s) that are missing on this computer”. There are many different reason as to why someone will get this error while you build the solution.

Error Details

This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is ..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props

Looking at the error, it is triggered from somewhere in the code. Let’s go to the .csproj file and this can be found at the end of the file.

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
  </Target>

A solution to “This project references NuGet package that are missing error”

The error is tied to the package Microsoft.CodeDom.Providers.DotNetCompilerPlatform. Follow the below three steps to solve the issue.

Step 1

Remove the package from package.config file.

<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net46" />

Step 2

Edit the .csproj project file and removed the below settings

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
  </Target>

Step 3

Go to package manager console and run the command Update-Package –reinstall

Step # 2 and 3 were given by other users and I appreciate those users. Point # 1, removing the Microsoft.CodeDom.Providers.DotNetCompilerPlatform from package.config file is more important. Also, after running the command mentioned in step #3, the issue resolved. All unwanted packages removed and required package reference updated

Reference

There are other similar fixes which might work for few scenarios. Take a look at this post from StackOverflow

Also Read

How to upload a file in ASP.NET Web API

Conclusion

In this post, I showed how to resolve a common error “This project references NuGet package(s) that are missing on this computer”. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post This project references NuGet package(s) that are missing on this computer. appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/c-sharp/this-project-references-nuget-package-that-are-missing-error/feed/ 0 463
Working with optional body parameters in ASP.NET Core 2.2 https://karthiktechblog.com/aspnetcore/working-with-optional-body-parameters-in-asp-net-core-2-2/?utm_source=rss&utm_medium=rss&utm_campaign=working-with-optional-body-parameters-in-asp-net-core-2-2 https://karthiktechblog.com/aspnetcore/working-with-optional-body-parameters-in-asp-net-core-2-2/#respond Sat, 04 Apr 2020 20:33:43 +0000 https://karthiktechblog.com/?p=444 Working with optional body parameters in ASP.NET Core 2.2 is now possible and I will show how to solve the issue in this post. Optional parameter exists in .Net for a long time. Specifying the default value used to be enough to mark them as optional. However, marking a body parameter in a Web API […]

The post Working with optional body parameters in ASP.NET Core 2.2 appeared first on KarthikTechBlog.

]]>
Working with optional body parameters in ASP.NET Core 2.2 is now possible and I will show how to solve the issue in this post. Optional parameter exists in .Net for a long time. Specifying the default value used to be enough to mark them as optional. However, marking a body parameter in a Web API action method is not going to work if you are working with .NET Core 2, 2.1 and 2.2 versions.

Let me explain the problem that you might face and a solution to solve the problem.

An issue in accepting body parameter as optional

I have a model class in my action method and that reads the content from the body as shown below.

        // POST api/values
        [HttpPost]
        public IActionResult Post([FromBody]ModelClass request = null)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            return Ok();
        }

Here is the problem, as soon as you include an attribute [FromBody], MVC binding will trigger. If you did not send content in the request body, you will see an error as shown below.

{
  "": [
    "A non-empty request body is required."
  ]
}

This is an existing issue in .NET Core 2.0. Optional body parameters no longer work since upgrading to .NET Core 2.0 #6920

Solution

One of the solutions is to read the content from the request body and then process it if it was sent in the request.

 string body;
            SomeClassModel model = null;
            using (var reader = new StreamReader(Request.Body, Encoding.UTF8, true, 1024, true))
            {
                body = reader.ReadToEnd();
            }

            if (!string.IsNullOrEmpty(body))
            {
               finalModel = JsonConvert.DeserializeObject(body);
            }

This way the body parameters can be made optional and custom validation can be implemented in case you need to validate a JSON string in the body parameter.

Related Posts

Implement create, read, update, and delete functionalities using Entity Framework Core

Conclusion

In this post, I showed how to work with optional body parameters in ASP.NET Core 2.2. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post Working with optional body parameters in ASP.NET Core 2.2 appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/aspnetcore/working-with-optional-body-parameters-in-asp-net-core-2-2/feed/ 0 444
How to upload a file with .NET CORE Web API 3.1 using IFormFile https://karthiktechblog.com/aspnetcore/how-to-upload-a-file-with-net-core-web-api-3-1-using-iformfile/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-upload-a-file-with-net-core-web-api-3-1-using-iformfile https://karthiktechblog.com/aspnetcore/how-to-upload-a-file-with-net-core-web-api-3-1-using-iformfile/#respond Sat, 04 Apr 2020 15:41:08 +0000 https://karthiktechblog.com/?p=434 In this post, I will show how to upload a file with .NET CORE Web API 3.1 using IFormFile. Uploading a file is a process of uploading a file from the user’s system to a hosted web application server. You may choose to store the file in the web server’s local disc or in the […]

The post How to upload a file with .NET CORE Web API 3.1 using IFormFile appeared first on KarthikTechBlog.

]]>
In this post, I will show how to upload a file with .NET CORE Web API 3.1 using IFormFile.

Uploading a file is a process of uploading a file from the user’s system to a hosted web application server. You may choose to store the file in the web server’s local disc or in the database.

With ASP NET CORE, it is easy to upload a file using IFormFile that comes under the namespace "Microsoft.AspNetCore.Http". IFormFile represents a file sent with the HttpRequest.

Upload File using IFormFile in .NET Core

Methods of uploading files have changed since DOT NET CORE was introduced. To upload a single file using .NET CORE Web API, use IFormFile which Represents a file sent with the HttpRequest.

This is how a controller method looks like which accepts a single file as a parameter.

[HttpPost("upload", Name = "upload")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> UploadFile(
         IFormFile file,
         CancellationToken cancellationToken)
        {
            if (CheckIfExcelFile(file))
            {
                await WriteFile(file);
            }
            else
            {
                return BadRequest(new { message = "Invalid file extension" });
            }

            return Ok();
        }

Code Explanation

The controller action method “UploadFile” accepts file using IFormFile as a parameter. We check whether the file sent is in the required format using a custom private method named “CheckIfExcelFile” which checks whether an incoming file is an excel file. You may change this based on your needs.

       
 private bool CheckIfExcelFile(IFormFile file)
        {
            var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
            return (extension == ".xlsx" || extension == ".xls"); // Change the extension based on your need
        }

Once the validation is a success, we save the file to the disc using “WriteFile(file)” method.

private async Task<bool> WriteFile(IFormFile file)
        {
            bool isSaveSuccess = false;
            string fileName;
            try
            {
                var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
                fileName = DateTime.Now.Ticks + extension; //Create a new Name for the file due to security reasons.

                var pathBuilt = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files");

                if (!Directory.Exists(pathBuilt))
                {
                    Directory.CreateDirectory(pathBuilt);
                }

                var path = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files",
                   fileName);

                using (var stream = new FileStream(path, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }

                isSaveSuccess = true;
            }
            catch (Exception e)
            {
               //log error
            }

            return isSaveSuccess;
        }

Yes, to upload a file with .NET CORE Web API 3.1 using IFormFile is very easy with DOTNET CORE Web API.

How to upload a file with .NET CORE Web API 3.1 using IFormFile

Here is the short video tutorial.

Upload file from Angular, Video demo

Complete Code

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace KarthikTechBlog.API.Controllers
{
    [HttpPost("upload", Name = "upload")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> UploadFile(
         IFormFile file,
         CancellationToken cancellationToken)
        {
            if (CheckIfExcelFile(file))
            {
                await WriteFile(file);
            }
            else
            {
                return BadRequest(new { message = "Invalid file extension" });
            }

            return Ok();
        }

        /// 
        /// Method to check if file is excel file
        /// 
        /// 
        /// 
        private bool CheckIfExcelFile(IFormFile file)
        {
            var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
            return (extension == ".xlsx" || extension == ".xls"); // Change the extension based on your need
        }

        private async Task<bool> WriteFile(IFormFile file)
        {
            bool isSaveSuccess = false;
            string fileName;
            try
            {
                var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
                fileName = DateTime.Now.Ticks + extension; //Create a new Name for the file due to security reasons.

                var pathBuilt = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files");

                if (!Directory.Exists(pathBuilt))
                {
                    Directory.CreateDirectory(pathBuilt);
                }

                var path = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files",
                   fileName);

                using (var stream = new FileStream(path, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }

                isSaveSuccess = true;
            }
            catch (Exception e)
            {
               //log error
            }

            return isSaveSuccess;
        }
    }
}

GitHub Code

You can get the complete code from github https://github.com/karthiktechblog/UploadFileUsingDotNETCore

Reference

Read more about IFormFile Interface
To upload multiple files, use IFormFileCollection Interface

Related Posts

Conclusion

In this post, I showed how to upload a file with .NET CORE Web API 3.1 using IFormFile. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post How to upload a file with .NET CORE Web API 3.1 using IFormFile appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/aspnetcore/how-to-upload-a-file-with-net-core-web-api-3-1-using-iformfile/feed/ 0 434
How to upload a file in ASP.NET Web API https://karthiktechblog.com/c-sharp/how-to-upload-a-file-in-asp-net-web-api/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-upload-a-file-in-asp-net-web-api https://karthiktechblog.com/c-sharp/how-to-upload-a-file-in-asp-net-web-api/#respond Sat, 04 Apr 2020 15:18:07 +0000 https://karthiktechblog.com/?p=430 In this short post, I will show how to upload a file in ASP.NET Web API. In this example, I will be using FormData to upload a file from any UI technology like JavaScript, Angular and much more. Using FormData FormData provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. The form uses “multipart/form-data” as encoding type and FormData does the same. […]

The post How to upload a file in ASP.NET Web API appeared first on KarthikTechBlog.

]]>
In this short post, I will show how to upload a file in ASP.NET Web API. In this example, I will be using FormData to upload a file from any UI technology like JavaScript, Angular and much more.

Using FormData

FormData provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method.

The form uses “multipart/form-data” as encoding type and FormData does the same.

Let’s jump into the coding part to see how to upload a file in ASP.NET Web API.

Upload Example

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace KarthikTechBlog.API.Controllers
{
    public class UploadController : ApiController
    {
        private readonly string uploadPath ="~/App_Data/uploads";
        private readonly List allowedFileExtensions = new List() { "pdf", "xlx", "doc", "docx", "xlxs" };

        [HttpPost]
        [ActionName("UploadFile")]
        public async Task UploadFile()
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }
            
            var provider = new MultipartMemoryStreamProvider();

            await Request.Content.ReadAsMultipartAsync(provider);

            var file = provider.Contents.FirstOrDefault();

            var fileExtension = file.Headers.ContentDisposition.FileName.Split('.')[1];
            if (!allowedFileExtensions.Any(a => a.Equals(fileExtension)))
            {
                return BadRequest($"File with extension {fileExtension} is not allowed");
            }

            await SaveFileToDisc(file, fileExtension); 
            
            await SaveFileToDatabase(file);

            return Ok();
        }

        private async Task SaveFileToDisc(HttpContent file, string extension)
        {
            var fileName = $"{DateTime.Now.Ticks}.{extension}"; 

            var root = System.Web.HttpContext.Current.Server.MapPath(uploadPath);

            var pathBuilt = Path.Combine(root, string.Concat(DateTime.Now.Month.ToString(), DateTime.Now.Day.ToString(), DateTime.Now.Year.ToString()));

            if (!Directory.Exists(pathBuilt))
            {
                Directory.CreateDirectory(pathBuilt);
            }

            var path = Path.Combine(pathBuilt, fileName);

            using (var stream = new FileStream(path, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }
        }

        private async Task SaveFileToDatabase(HttpContent file)
        {
            var byteArray = await file.ReadAsByteArrayAsync();
            var base64String = Convert.ToBase64String(byteArray); // Save this base64 string to database
        }

    }
}

With upload functionality, you can save the incoming file to a disc or save the file to a database after encoding the file to standard Base64 string. You may also perform both operations like saving the file to disc and to the database.

Are you looking for similar upload functionality in ASP NET CORE 3.1? Read this post for more details.

Reference

to read more about MultipartMemoryStreamProvider, visit MultipartStreamProvider Class in MSDN

Related Posts

Conclusion

In this post, I showed how to upload a file in ASP.NET Web API. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post How to upload a file in ASP.NET Web API appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/c-sharp/how-to-upload-a-file-in-asp-net-web-api/feed/ 0 430
How to cast int to enum in C# https://karthiktechblog.com/c-sharp/how-to-cast-int-to-enum-in-c-sharp/?utm_source=rss&utm_medium=rss&utm_campaign=how-to-cast-int-to-enum-in-c-sharp https://karthiktechblog.com/c-sharp/how-to-cast-int-to-enum-in-c-sharp/#respond Wed, 15 Jan 2020 03:03:36 +0000 https://karthiktechblog.com/?p=326 Introduction In this short post, I show How to cast int to enum in C#. We have used an enumeration type (or enum type) in our day to day programming. Enum is a value type defined by a set of named constants of the underlying integral numeric type. To define an enumeration type, we used […]

The post How to cast int to enum in C# appeared first on KarthikTechBlog.

]]>
Introduction

In this short post, I show How to cast int to enum in C#. We have used an enumeration type (or enum type) in our day to day programming. Enum is a value type defined by a set of named constants of the underlying integral numeric type. To define an enumeration type, we used the enum keyword and specified the names of enum members as shown in below example.

public enum OrderStatus
{
Received = 1,
InProgress = 2,
Processed = 3,
Shipped = 4
}

How to convert int to enum ?

Let’s take an example to demonstrate real time scenario. Consider we have a field that represents order status for a given product order.

public OrderStatus Status {get; set;}

OrderStatus is the enum that is defined with various status. E.g. Received, InProgress, Processed and Shipped.

Say you need to convert int or string to enum, it is easy to do so.

OrderStatus variableName = (OrderStatus)Enum.Parse(typeof(OrderStatus), yourStringVariable);

Yes, it is that easy to cast int to enum type.

Validate enum property in model

Say, your enum property needs to be validated in a given model, simple use the EnumDataType as shown below.

[Required]
[EnumDataType(typeof(OrderStatus), ErrorMessage = "Provide initial order status")]
public OrderStatus Status { get; set; }

Resource

Read more on Enum

Interested in Azure certification? Take a look at my post EXAM AZ-203: DEVELOPING SOLUTIONS FOR MICROSOFT AZURE

Conclusion

In this short post, I showed how to cast int or string to enum in C#. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below.

The post How to cast int to enum in C# appeared first on KarthikTechBlog.

]]>
https://karthiktechblog.com/c-sharp/how-to-cast-int-to-enum-in-c-sharp/feed/ 0 326