Developing MVC applications using SOLID principles

0

Category : ,

my thanks to: Developing MVC applications using SOLID principles http://www.codeguru.com/csharp/csharp/writing-c-code-using-solid-principles.htm

MVC in a nutshell

0

Category :

Getting Data from Controller to View

  1. ViewData - Assign a value with a key in the controller and read the value using the key in the View page
    public ActionResult Index()
    {
      ViewData["Message"] = "Hello, World";
      return View();
    }
    
  2. ViewBag - allows an object to dynamically have properties added to it. So with a ViewBag, you can use the “.” notation.
    public ActionResult Index()
    {
      ViewBag.Message = "Hello, World";
      return View();
    }
    
  3. TempData - is another dictionary for storing temporary data like the “ViewBag“ but is deleted at the end of the HTTP request
    //  marks the specified key in the dictionary for retention
    public void Keep(string key)
    // returns an object without marking the key for deletion
    public Object Peek(string key)
    
  4. Strongly-Typed View Model Object – WebFormViewEngine
    <%@ Page Inherits="System.Web.Mvc.ViewPage" %>
    

    Product Name: <%: Model.Name %>

  5. Strongly-Typed View Model Object – Razor
    @model Mvc3App.Models.Product
    

    Product: @Model.Name


Getting Data from View to Controller

  1. Traditional Approach - HttpRequestBase
  2. FormCollection Object
  3. Action Parameters
  4. Strongly type model binding to view

ActionResult() response types:

There are 11 different response types which can be sent to the end user :-
  1. ViewResult - Renders a specified view to the response stream
  2. PartialViewResult - Renders a specified partial view to the response stream
  3. EmptyResult - An empty response is returned
  4. RedirectResult - Performs an HTTP redirection to a specified URL
  5. RedirectToRouteResult - Performs an HTTP redirection to a URL that is determined by the routing engine, based on given route data
  6. JsonResult - Serializes a given object to JSON format
  7. JavaScriptResult - Returns a piece of JavaScript code that can be executed on the client
  8. ContentResult - Writes content to the response stream without requiring a view
  9. FileContentResult - Returns a file to the client
  10. FileStreamResult - Returns a file to the client, which is provided by a Stream
  11. FilePathResult - Returns a file to the client

C# 6.0 features

0

Category :

Primary Constructor

When declaring a primary constructor all other constructors must call the primary constructor using :this().
class Person(string name, int age)
{
    private string _name = name;
    private int _age = age;
 
    private string _address;
 
    public Person(string name, int age, string address) : this(name, age)
    {
         _address = address;
    }
 
    public void Speak()
    {
        Console.WriteLine("Hi, my name is {0} and I am {1} years old", _name, _age);
    }
}

Auto-properties

class Person(string name, int age)
{
    public string Name { get; set; } = name;
    public string Name1 { get; } = name;
}

Dictionary initializer

When using dictionaries, sometimes you want to initialize them with values just as you can do with arrays and lists.
You will see in the following code sample that these new initializers even work with instance variables.
class Person(string name)
{
    private Dictionary _data = new Dictionary {["Name"] = name };

    Dictionary newWay = new Dictionary()
            {
                // Look at this!
                ["Afghanistan"] = "Kabul",
                ["Iran"] = "Tehran",
                ["India"] = "Delhi"
            };
}
It will of course also work with the auto-property initializers
class Person(string name, int age)
{
         
    public Dictionary Data { get; } = new Dictionary {["Name"] = name };
}

Declaration expressions

With the out keyword you would have to declare a variable for the result before calling the actual method.
int age;
CalculateAgeBasedOn(1987, out age);
We no longer have to do that
CalculateAgeBasedOn(1987, out var age);

Using await in a catch or finally block

Consider logging for instance. You may want to write a file log when you catch an error but not hold up the caller for too long. In this scenario, it would be great to have the ability to await an asynchronous call inside the catch block.
Equally when talking about the finally block, we may want to clean up some resources or do something particular inside the finally block that invokes an asynchronous API. As seen in the following code sample, this is now allowed.
public async Task DownloadAsync()
{
    try
    {}
    catch
    {
        await Task.Delay(2000);
    }
    finally
    {
        await Task.Delay(2000);
    }
}

Filtering Exceptions with Exception Filters

try
{
    throw new CustomException { Severity = 100 };
}
catch (CustomException ex) if (ex.Severity > 50)
{
    Console.WriteLine("*BING BING* WARNING *BING BING*");
}
catch (CustomException ex) // to catch all other exceptions
{
    Console.WriteLine("Whooops!");
}
my thanks to: http://www.codeproject.com/Articles/808732/Briefly-exploring-Csharp-new-features
http://www.dotnetcurry.com/showarticle.aspx?ID=1042

CRUD Opearations using AutoMapper

0

Category :

Challenge

Sometimes while interacting with real time (database) entities and binding our model to them, we end up in a situation like:

var dbContext = new MyDBDataContext();
var userDetails = dbContext.Users.FirstOrDefault(userId => userId.UserId == id);
var user = new LearningMVC.Models.User();
if (userDetails != null)
{
    user.UserId = userDetails.UserId;
    user.FirstName = userDetails.FirstName;
    user.LastName = userDetails.LastName;
    user.Address = userDetails.Address;
    user.PhoneNo = userDetails.PhoneNo;
    user.EMail = userDetails.EMail;
    user.Company = userDetails.Company;
    user.Designation = userDetails.Designation;
}
return View(user);
We have an existing model named User (LearningMVC.Models.User()) that has similar properties as that of the Users class generated from the database. Now we initialize properties of the instance of our model from properties of instance of the User class from the database so that we can populate our View in an MVC application.

Now the problem is what if we have 100 column records coming from the database, and also our model has the same number of properties, and the code has to be repeated 6-7 times at different scenarios?

Auto Mapper

As per the AutoMapper CodePlex webpage: "AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. What makes AutoMapper interesting is that it provides some interesting conventions to take the dirty work out of figuring out how to map type A to type B. As long as type B follows AutoMapper's established conventions, almost zero configuration is needed to map two types." Therefore, it provides the solution for our mapping issue.

Example

public ActionResult Index()
{
    var dbContext = new MyDBDataContext();
    var userList = from user in dbContext.Users select user;
    var users = new List();
    if (userList.Any())
    {
        foreach (var user in userList)
        {
            users.Add(new LearningMVC.Models.User()
                {
                    UserId = user.UserId, 
                    Address = user.Address, 
                    Company = user.Company, 
                    FirstName = user.FirstName,
                    LastName = user.LastName,
                    Designation = user.Designation,
                    EMail = user.EMail, 
                    PhoneNo = user.PhoneNo
                });
        }
    }
  
    return View(users);
}
To create the default mapping, call Mapper.CreateMap() with proper types. In this case, T1 will be LearningMVC.User and T2 will be LearningMVC.Models.User.

Mapper.CreateMap();
Now inside the foreach loop, replace the whole code by:
LearningMVC.Models.User userModel = Mapper.Map(user);
users.Add(userModel);
So, our final Action code:
public ActionResult Index()
{
    Mapper.CreateMap();
    var dbContext = new MyDBDataContext();
    var userList = from user in dbContext.Users select user;
    var users = new List();
    if (userList.Any())
    {
        foreach (var user in userList)
        {
            LearningMVC.Models.User userModel = 
              Mapper.Map(user);
            users.Add(userModel);
        }
    }
    return View(users);
}

ForMember() and MapFrom() in AutoMapper

Two important functions in AutoMapper play an important role in object mapping. Suppose our model/viewmodel class has a property FullName, and from the DTO we want to add the First Name and Last Name of the user to make it a full name and bind it to the model. For these kinds of scenarios ForMember() and MapFrom() come in handy.

Mapper.CreateMap().ForMember(emp => emp.Fullname,
map => map.MapFrom(p => p.FirstName + " " + p.LastName));
Here we are saying that ForMember FullName in our model class maps properties from FirstName and LastName of User DTO.

my thanks to: http://www.codeproject.com/Articles/639618/CRUD-Opearations-using-AutoMapper-in-an-MVC-Applic

Passing Data From View to Controller

0

Category :

Using Traditional Approach

In the traditional approach we use the request object of the HttpRequestBase class. The request object has view input field values in name/value pairs.
[HttpPost]
public ActionResult CalculateSimpleInterestResult()
{
    decimal principle = Convert.ToDecimal(Request["txtAmount"].ToString());
    decimal rate = Convert.ToDecimal(Request["txtRate"].ToString());
    int time = Convert.ToInt32(Request["txtYear"].ToString());

    decimal simpleInteresrt = (principle*time*rate)/100;

    StringBuilder sbInterest = new StringBuilder();
    sbInterest.Append("Interest : " + simpleInteresrt);
    return Content(sbInterest.ToString());
}

Using the FormCollection Object

We can also get post requested data by the FormCollection object. The FormCollection object also has requested data in the name/value collection as the Request object. To get data from the FormCollection object we need to pass it is as a parameter and it has all the input field data submitted on the form.
[HttpPost]
public ActionResult CalculateSimpleInterestResult(FormCollection form)
{
    decimal principle = Convert.ToDecimal(form["txtAmount"].ToString());
    decimal rate = Convert.ToDecimal(form["txtRate"].ToString());
    int time = Convert.ToInt32(form["txtYear"].ToString());

    decimal simpleInteresrt = (principle*time*rate)/100;

    StringBuilder sbInterest = new StringBuilder();
    sbInterest.Append("Interest : " + simpleInteresrt);
    return Content(sbInterest.ToString());
}

Using the Parameters

We can pass all input field names as a parameter to the post action method. The input field name and parameter name should be the same. These parameters have input field values that were entered by the user. So we can access view input field values from these parameters. The input field takes a string value from the user so the parameter should be a string type. There is no need to define a parameter in any specific sequence.
[HttpPost]
public ActionResult CalculateSimpleInterestResult(string txtAmount, string txtRate, string txtYear)
{
    decimal principle = Convert.ToDecimal(txtAmount);
    decimal rate = Convert.ToDecimal(txtRate);
    int time = Convert.ToInt32(txtYear);

    decimal simpleInteresrt = (principle*time*rate)/100;

    StringBuilder sbInterest = new StringBuilder();
    sbInterest.Append("Interest : " + simpleInteresrt);
    return Content(sbInterest.ToString());
}

Strongly typed model binding to view

We bind a model to the view; that is called strongly type model binding.
namespace CalculateSimpleInterest.Models
{
    public class SimpleInterestModel
    {
        public decimal Amount { get; set; }
        public decimal Rate { get; set; }
        public int Year { get; set; }
    }
}
[HttpPost]
public ActionResult CalculateSimpleInterestResult(SimpleInterestModel model)
{
    decimal simpleInteresrt = (model.Amount*model.Year*model.Rate)/100;

    StringBuilder sbInterest = new StringBuilder();
    sbInterest.Append("Interest : " + simpleInteresrt);
    return Content(sbInterest.ToString());
}
my thanks to: http://www.codeproject.com/Articles/639709/Getting-Data-From-View-to-Controller-in-MVC