Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC - data calculations best practice - viewmodel vs. controller

rI need some advice on where to run a calculation on data.

I have a viewmodel that contains all the fields that I need for my calculation and I created the following for one of my calculations:

public class CommissionVM
{
public int? LoanAmountLock { get; set; } // from loan table    
public decimal BranchRev { get; set; }   // from revenue table
public decimal BranchProcessFee { get; set; }   // from revenue table

public decimal BranchGrossTotal
    {
        get
        {               

            return Convert.ToDecimal(LoanAmountLock * (BranchRev/ 100) + BranchProcessFee);
        }
    }

}

I tried to use the Model.BranchGrossTotal in my view, but it is returning 0. I think I have an order-of-operations problem. The values LoanAmountLock, BranchRev, and BranchProcessFee are returned as the results of a query:

public ActionResult Reconcile(int? id, string RevenueLoanType)
    {
var model = new CommissionVM()
        {

            Loan = db.Loan.FirstOrDefault(a => a.id == id ),                
            BranchRevenues = db.BranchRevenues.FirstOrDefault(a => a.RevenueLoanType == RevenueLoanType),  
        };
return View(model);
}

I originally was able to get these calculations to work by doing all the math in the controller after I populate the viewmodel with the query, but there will be about 10 calculations, and from what I understand, I shouldn't clutter up my controller with business logic.

What is the best solution for this? Do I need to create another class for the calculations? If so, how do I populate that class with my data and use it in my controller?

EDIT: I am not sure how to set up the business classes and use them in the controller. Can anyone point me in the direction of a tutorial?

like image 303
Daniela Avatar asked Jul 30 '15 17:07

Daniela


People also ask

What is the difference between ViewModel and controller?

The view renders presentation of the model in a particular format. The controller responds to the user input and performs interactions on the data model objects. The controller receives the input, optionally validates it and then passes the input to the model.

Why use ViewModel in MVC?

In ASP.NET MVC, ViewModel is a class that contains the fields which are represented in the strongly-typed view. It is used to pass data from controller to strongly-typed view.

Why do we need ViewModel?

The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.

What is difference between model and ViewModel?

ViewModel in the MVC design pattern is very similar to a "model". The major difference between "Model" and "ViewModel" is that we use a ViewModel only in rendering views. We put all our ViewModel classes in a "ViewModels" named folder, we create this folder.


2 Answers

You should not do the calculation in your controller nor in your view model. You should do it in the Business Layer. Think about View Models are really simple classes that contain data to be displayed to the user, that's it.

Regarding the calculation, you should convert one of the terms to decimal, not the result of the calculation. If you divide integers, you get an integer.

You could create a class and call it CommissionService for example. That class should call your Data Layer to get the data, do any extra calculation and return the data (maybe a DTO) to the controller. The controller should create View Models based on the DTO and send them to the view.

enter image description here

Read these articles:

1) https://msdn.microsoft.com/en-us/library/hh404093.aspx

2) http://www.asp.net/mvc/overview/older-versions-1/models-%28data%29/validating-with-a-service-layer-cs

3) http://blog.diatomenterprises.com/asp-net-mvc-business-logic-as-a-separate-layer/

4) http://sampathloku.blogspot.com.ar/2012/10/how-to-use-viewmodel-with-aspnet-mvc.html

like image 114
Francisco Goldenstein Avatar answered Oct 01 '22 04:10

Francisco Goldenstein


I don't like calculations on my view models -- you can't reuse the calculation easily elsewhere and it is harder to test and debug. Create separate classes to do business logic.

Your business logic classes can either return your view models or return values you use to populate those models. The trade-off is ease of use with reusability.

I generally favor returning the value rather than a big object so my services are more reusable.

Controller

public class BranchController : Controller
{
    private IBusinessService service;

    public BranchController()
    {
        this.service = new BusinessService(db);
    }

    public ActionResult Reconcile(int? id, string RevenueLoanType)
    {
        var model = new CommissionVM
        {
            BranchGrossTotal = this.service.GetBranchGrossTotal(id, RevenueLoanType),
            ...
        };

        return View(model);
    }
}

Service

You can make any number of these and your controllers would use them as needed. If you need a query you should pass the DbContext instance or you may have problems with related entities on separate contexts.

public interface IBusinessService
{
    decimal GetBranchGrossTotal(int id, string revenueLoanType);
}

public class BusinessService : IBusinessService
{
    private DbContext db;

    public BusinessService(DbContext db)
    {
        this.db = db;
    }

    public decimal GetBranchGrossTotal(int id, string revenueLoanType)
    {
        var branch = db.Branch.First(b => b.Id == id);
        // do stuff
        return total;
    }
}

You could fully-populate and return a view model in your GetBranchGrossTotal() if you choose.

like image 25
Jasen Avatar answered Oct 01 '22 04:10

Jasen