European ASP.NET MVC Hosting

BLOG about Latest ASP.NET MVC Hosting and Its Technology - Dedicated to European Windows Hosting Customer

ASP.NET MVC Hosting - HostForLIFEASP.NET :: Implement Cascading Dropdown In ASP.NET Core MVC Application Using InMemory DB

clock May 17, 2023 10:15 by author Peter

Today, this article will discuss how we can design or develop any dependent or cascading dropdown control in Asp.net Core MVC Application. While developing any application using any language, sometimes we must define dropdown control that populates data from the backend part, i.e., from the database section. So, control directly fetches data from the database by using APIs and displays it in the dropdown control. But, sometimes, we need to implement the dependent dropdown control. It means the value of the dependent dropdown control depends on another. So, as per the selected value of the first dropdown control, we need to pass that value to the database side with the help of a parameter, and then as per that value, it will return the corresponding values to bind the second control. In this article, we will demonstrate this function with the help of the Asp.Net Core MVC Application.


Pre-Requisites
We must create a sample application using Asp.Net Core to demonstrate the functionality. For that purpose, we will use the .Net 7.0 framework. So, we need the below tools as a pre-requisite.
    Visual Studio 2022 Community Edition / Visual Studio Code
    .Net 7.0 SDK (only required if we use Visual Studio Code as Code Editor).

Also, we are not using any database tools for the database-related part. For the time-saving part, we are using the In-Memory database features of the Asp.Net Core application. We must use database tools like SQL, Oracle, MySQL, etc. In that case, we can need to replace the In-Memory database connection part with the actual database connection details.

In this example, we will use two models: Category and Product. Every product information is tagged with an existing category. So, finally, in the view part, once we select any Category value from the dropdown, it will populate related product items accordingly.
Steps to Develop Cascading Dropdown in Asp.Net Core MVC

Step 1
Open Visual Studio 2022 and click on Create New Project with the template "Asp.Net Core Web App (Model-View-Controller)."

Step 2
Then click on the Next Button and provide the Project Name.

Step 3
Then click on the Next Button and select .Net 7.0 as the Framework version. (If anyone is using VS 2019, then also select .Net 5.0 or .Net 6.0)

Step 6
Select the Model folder, create a new class file called Category.cs, and add the code below.
public class Category {
    public int Id {
        get;
        set;
    }
    public string Name {
        get;
        set;
    }
    public virtual List < Product > Products {
        get;
        set;
    }
}

Step 7
Again, add another new file called Product.cs and add the below code –
public class Product {
    public int Id {
        get;
        set;
    }
    public string Code {
        get;
        set;
    }
    [Required]
    public string Name {
        get;
        set;
    }
    [MaxLength(255)]
    public string ? Description {
        get;
        set;
    }
    public decimal Price {
        get;
        set;
    }
    public bool IsAvailable {
        get;
        set;
    }
    public int CategoryId {
        get;
        set;
    }
    [JsonIgnore]
    public virtual Category Category {
        get;
        set;
    }
}


Step 8

Now, we need to create the DBContext File. So, we need to add a new file called InMemoryDBContext.cs file and the below code in that file.
public class InMemoryDBContext: DbContext {
    public InMemoryDBContext(DbContextOptions < InMemoryDBContext > options): base(options) {}
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.Entity < Category > ().HasMany(c => c.Products).WithOne(a => a.Category).HasForeignKey(a => a.CategoryId);
        modelBuilder.Seed();
    }
    public DbSet < Product > Products {
        get;
        set;
    }
    public DbSet < Category > Categories {
        get;
        set;
    }
}

Step 9
In the above code, we invoke the Seed() of the ModelBuilder. This method is responsible for initiating the base data related to the Category and Product. For that purpose, we have created a static call called ModelBuilderExtensions and implemented the Seed() method in that class with some sample data. So, we call the Category or Product list from the View Part; it populates the data from this list.

Step 10
After that, we need to open the Program.cs File and add the below code in that File.
builder.Services.AddDbContext<InMemoryDBContext>(options => options.UseInMemoryDatabase("Shop"));
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
    // options.SuppressModelStateInvalidFilter = true;
  }
);


Step 11

Now, we can perform the scaffold function of the Asp.Net Core MVC Application to generate the entire View & Controller layer related to the Category and Products. Once the scaffold files are created, we can execute the application and display just like below for both category and product parts.


 

Step 12
Now, open the Index.cshtml view under the Home folder. There add the below code to populate two different dropdown control related to the Category and Product list.
@{
    ViewData["Title"] = "Home Page";
    var baseurl = ViewBag.BaseUrl;
}

<div class="text-center">
    <h2>Cascading Dropdown Demo</h2>

    <div class="row form-group">
        <div class="col-md-2">
            <label asp-for="CategoryId" class="control-label"></label>
        </div>
        <div class="col-md-4">
            <select asp-for="CategoryId" class="form-control"
                    asp-items="ViewBag.CategoryData"
                    id="CategoryId"></select>
        </div>
        <div class="col-md-2">
            <label asp-for="ProductId" class="control-label"></label>
        </div>
        <div class="col-md-4">
            <select asp-for="ProductId" class="form-control" asp-items="ViewBag.ProductData" id="ddlProductId"></select>
        </div>
    </div>
</div>


Step 13
Now, open the HomeController.cs file under the controller folder and add the below code in the Index Action method. This code will fetch the Category and the Product list and return it as a view bag object. Initially, it does not produce any list value of the Product, as it will only populate if we pass any category id value to filter the product list.
public class HomeController: Controller {
    private readonly ILogger < HomeController > _logger;
    private readonly InMemoryDBContext _context;
    public HomeController(ILogger < HomeController > logger, InMemoryDBContext context) {
        _logger = logger;
        _context = context;
        _context.Database.EnsureCreated();
    }
    public IActionResult Index() {
        var _categories = _context.Categories.ToList();
        var _products = new List < Product > ();
        _categories.Add(new Category() {
            Id = 0, Name = "--Select Category--"
        });
        _products.Add(new Product() {
            Id = 0, Name = "--Select Product--"
        });
        ViewData["CategoryData"] = new SelectList(_categories.OrderBy(s => s.Id), "Id", "Name");
        ViewData["ProductData"] = new SelectList(_products.OrderBy(s => s.Id), "Id", "Name");
        string host = $ "{Request.Scheme}://{Request.Host}{Request.PathBase}/";
        ViewData["BaseUrl"] = host;
        return View();
    }
    public IActionResult Privacy() {
            return View();
        }
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error() {
        return View(new ErrorViewModel {
            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
        });
    }
}


Step 14
Now, we can run the application and check that the category dropdown already binds with the existing category data. But, the product dropdown does secure any data.

Step 15
We need to add a new action method to return the filtered product list as per the selected category id. This method accepts one input value called categoryId from the View part, and as per that categoryId, it will filter the product list and return the data in a JSON format. For that, open the ProductController.cs file and add the code below.
[HttpPost, ActionName("GetProductsByCategoryId")]
public JsonResult GetProductsByCategoryId(string categoryId) {
    int catId;
    List < Product > productLists = new List < Product > ();
    if (!string.IsNullOrEmpty(categoryId)) {
        catId = Convert.ToInt32(categoryId);
        productLists = _context.Products.Where(s => s.CategoryId.Equals(catId)).ToList();
    }
    return Json(productLists);
}

Step 16
We must consume the above action method from the view to retrieve the JSON data and bind it with the product dropdown. For that, we will take the help of JQuery code. Now, return to the Index.cshtml file under the home folder and add the below code there under script sections –
@section scripts
    {
    <script type="text/javascript">
        $(document).ready(function () {
            var a = 0;
        });
        function loadProduct(obj) {
            var value = obj.value;
            var url = "@baseurl";
            $.post(url + "Products/GetProductsByCategoryId", { categoryId: value }, function (data) {
                debugger;
                PopulateDropDown("#ddlProductId", data);
            });
        }
        function PopulateDropDown(dropDownId, list, selectedId) {
            $(dropDownId).empty();
            $(dropDownId).append("<option>--Please Product--</option>")
            $.each(list, function (index, row) {
                $(dropDownId).append("<option value='" + row.id + "'>" + row.name + "</option>")
            });
        }
    </script>
}


Step 17    
Now, invoke the loadProduct() method from the HTML part related to the Product dropdown. For that, change the code related to the product dropdown as below –
<select asp-for="CategoryId" class="form-control"
                   asp-items="ViewBag.CategoryData"
                   id="CategoryId" onchange="loadProduct(this)"></select>

Step 18
Now, run the application, select any category from the dropdown, and check related products populated within the product dropdown.


This article discusses cascading dropdown generation using the Asp.Net Core MVC application. Also, we discussed the steps related to implementing the In-Memory database concept. Any suggestions, feedback, or queries related to this article are appreciated.



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Remote Validation in MVC

clock May 12, 2023 09:07 by author Peter

Hello everyone, in this post I'll describe how to integrate remote validation into MVC. Remote validation is the technique by which we verify particular data before publishing it to a server without posting the complete form's data. Let's look at a real-world example. In one of my projects, I had to verify that an email address didn't already exist in the database.

Remote validation was helpful in that regard because it allowed us to validate simply the user-supplied email address without submitting the rest of the data.Explanation in PracticeLet's create an MVC project and give it the appropriate name—for me, "TestingRemoteValidation"—then proceed. Let's create a model called UserModel once the project has been built. Its design will be as follows:
    public class UserModel  
    {
        [Required]
        public string UserName { get; set; }
        [Remote("CheckExistingEmail","Home",ErrorMessage = "Email already exists!")]
        public string UserEmailAddress { get; set; }
    }

Let's get some understanding of the remote attribute used, so the very first parameter “CheckExistingEmail” is the name of the action. The second parameter “Home” is referred to as controller so to validate the input for the UserEmailAddress the “CheckExistingEmail” action of the “Home” controller is called and the third parameter is the error message. Let's implement the “CheckExistingEmail” action result in our home controller.
    public ActionResult CheckExistingEmail(string UserEmailAddress)
    {
        bool ifEmailExist = false;
        try
        {
            ifEmailExist = UserEmailAddress.Equals("[email protected]") ? true : false;
            return Json(!ifEmailExist, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            return Json(false, JsonRequestBehavior.AllowGet);
        }
    }


For simplicity I am just validating the user input with a hard-coded value but we can call the database and determine whether or not the given input exists in the database.

Let's create the view using the defined “UserModel” and using the create scaffold template; the UI will look like:

We will get the following output if we use “[email protected]” as UserEmailAddress:



ASP.NET MVC Hosting - HostForLIFEASP.NET :: Three Different Ways to Upload a File in ASP.NET MVC

clock May 5, 2023 08:41 by author Peter

There are a few things that all web applications have in common. File Upload is one of the most common things that all web applications have. This is used to move data, upload large amounts of data, upload pictures, videos, etc.


I've mostly seen three ways to share a file while working on different web apps and products, especially in ASP.NET MVC. We will look at it in depth.

1. File Control with Html.BeginForm
When we submit the form, we can post our selected file to the server and read it. Below is the code to bind the File control
@Html.TextBoxFor(model =>
       model.DocumentFile, new {
                type = "file",
                @id = "documentFile"

})


And the type of DocumentFile property is as below.
public HttpPostedFileBase DocumentFile { get; set; }

To save this file, we created one folder and added the path of the folder in the config. We are accessing the folder location as below
var path = ConfigurationManager.AppSettings["CustomerDocuments"].ToString();


Now we need to save the file in the folder and insert the path of the file in the database

if (objGroup.GSTDocumentFile != null)
{
     using (Stream inputStream = objGroup.GSTDocumentFile.InputStream)
     {
         byte[] data;
         using (MemoryStream ms = new MemoryStream())
         {
             inputStream.CopyTo(ms);
             data = ms.ToArray();
         }
         System.IO.File.WriteAllBytes(Path.Combine(ClientFolder, objGroup.GSTDocumentFile.FileName), data);
     }
        objGroup.Document = objGroup.DocumentFile.FileName;
}


2. File upload using AJAX - Base64 as a parameter
When we select a file using file upload on the browser, we need to fire an event to capture the file like below
document.getElementById("uploadfile").addEventListener('change', handleFileSelect, false);

Using this event listener, we execute the function on selection of file and capture the file as below
function handleFileSelect(evt) {

     const id = evt.currentTarget.id;
     const f = evt.target.files[0];
     const Name = evt.target.files[0].name;
     const reader = new FileReader();

     reader.onload = (function(theFile) {

          return function(e) {

               const binaryData = e.target.result;
               const base64String = window.btoa(binaryData);

               $("#uploadDocBase64").val(base64String);
               $("#uploadFileName").val(Name);

          };

     })(f);

     reader.readAsBinaryString(f);

}


Here we capture the  file as well as the file name, and using AJAX, we can send this file to the server
try {

  const response = await fetch('@Url.Action("FileUpload", "Upload")', {
    method: 'POST',
    body: JSON.stringify({ fileStr: $("#uploadDocBase64").val() }),
    headers: {
      'Content-Type': 'application/json; charset=utf-8'
    }
  });

  const result = await response.json();

  alert('Success');

} catch (error) {

  alert('Failure');
  console.error(error);

}


System.IO.File.WriteAllBytes(path, Convert.FromBase64String(Convert.ToString(fileStr)));

3. File Upload using Fetch with FileData

There is an issue with option no 2. Big files are not getting uploaded as it is going in the parameter. To overcome this, we can add all the parameters and files in fileData and upload a file.
try {

  const fileData = new FormData();

  fileData.append("File", $("#uploadDocBase64").val());

  const response = await fetch('@Url.Action("UpdateStatusAndDiscussion", "Discussion")', {
    method: 'POST',
    body: fileData,
  });

  if (response.ok) {
    alert("Success");
  } else {
    alert("Failure");
  }

} catch (error) {
  console.error(error);
}


Now you can capture the file in the controller
byte[] imageBytes = Convert.FromBase64String(File);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
path = HttpContext.Current.Server.MapPath("~/FileUpload/" + _GroupName + "/" + DoneFileName);
FileStream fileNew = new FileStream(path, FileMode.Create, FileAccess.Write);
ms.WriteTo(fileNew);
fileNew.Close();
ms.Close();


These are the ways to upload files to the server using ASP.NET MVC.




About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Tag cloud

Sign in