0

Hi there fellow coders,

I'm pretty new to ASP.Net MVC and I'm finding it difficult to figure out how to do calculations using data from different entities.

So I have 3 tables with their corresponding attributes:

Presenter

  • Name
  • MinimumWage
  • TaxDeduction

Video

  • Title
  • Likes
  • RatePerLike

Payment

  • GrossPay
  • Deductions
  • NettPay

Presenter has been linked to Payment and Video as a foreign key.

So these tables have been created in SQL. The models have been created accordingly in Visual Studio 2015. I've also used scaffolding to create the controllers.

Now my problem is coming in when I'm trying to create a new entry in the Payment table.

Essentially, what needs to happen is all the Payment attributes should be done through calculations using data from the other 2 tables according to which Presenter has been selected. All there is on the Payment Create View is a DropDownList for Presenters and a button to execute the payment for that particular Presenter.

Like this:

  • GrossPay = (Presenter.MinimumWage + (Video.Likes * Video.RatePerLike)
  • Deductions = (GrossPay * (Presenter.TaxDeduction / 100)
  • NettPay = (GrossPay - Deductions)

I'm finding it really difficult to find something online to help me with this.

Your help will be greatly appreciated, and if there is any other info you require, please let me know.

Please find code below:

Payment Model

public partial class Payment
{
    public int PaymentId { get; set; }
    public double GrossPay { get; set; }
    public int PresenterId { get; set; }

    public Presenter Presenter { get; set; }

    public double calcGrossPay()
    {
        Video v = new Video();
        double gross = 0.0;

        gross = (Presenter.MinimumWage + (v.Likes * v.RatePerLike));

        return gross;
    }

}

Video Model

 public partial class Video
{
    public int VideoId { get; set; }
    public string Title { get; set; }
    public int PresenterId { get; set; }
    public int Likes { get; set; }
    public double RatePerLike { get; set; }

    public virtual Presenter Presenter { get; set; }
}

Presenter Model

public partial class Presenter
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Presenter()
    {
        this.Payments = new HashSet<Payment>();
        this.Videos = new HashSet<Video>();
    }

    public int PresenterId { get; set; }
    public string Name { get; set; }
    public string Contact { get; set; }
    public string Email { get; set; }
    public double MinimumWage { get; set; }
    public double TaxDeduction { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Payment> Payments { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Video> Videos { get; set; }
}

Payment Controller (Create)

        [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "PaymentId,GrossPay,PresenterId")] Payment payment)
    {
        if (ModelState.IsValid)
        {
            payment.GrossPay = payment.calcGrossPay();
            db.Payments.Add(payment);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.PresenterId = new SelectList(db.Presenters, "PresenterId", "Name", payment.PresenterId);
        return View(payment);
    }

Payment View (Create)

<div class="form-group">
        @Html.LabelFor(model => model.PresenterId, "PresenterId", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("PresenterId", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.PresenterId, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>

I just can't seem to wrap my head around how to define the parameters accordingly or how to parse data between the models.

Error

Mavric
  • 25
  • 7
  • Write code to retrieve the data you need in your calculation, run it through some functions that perform the calculations, create a new Payment record to store the results? Seems pretty straightforward. Why don't you actually try implementing it and then show us where you are stuck, making sure to provide the code. – mason Apr 10 '17 at 12:11
  • Hi @mason. Thank you for responding. I've added the code and the error accordingly. I know it's something simple, I just can't get my head around it. As you can see, I've also only tried GrossPay for now and once I figure that out, I'm sure I can do the other entries – Mavric Apr 10 '17 at 12:39
  • You have a NullReferenceException. `Presenter` is null. You can't access properties of objects that are null. See [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142) – mason Apr 10 '17 at 12:55
  • I created an instance of Presenter. It cancels out the error and I just get a zero value for GrossPay. My problem is how to parse the parameter according to the presenter selected. – Mavric Apr 10 '17 at 13:10
  • That's the problem, you *didn't* create an instance of Presenter. Your Payment gets posted to the controller, and you're relying on the model binder to create the presenter. But it's not creating it. It gets the PresenterId but the model binder won't go to EF and retrieve the corresponding Presenter from the database. That's part of the trouble of allowing users to Post domain models. View models are better suited for that. As a workaround, you can grab the PresenterId and then use that to retrieve the correct Presenter and assign it to the payment yourself. – mason Apr 10 '17 at 13:14
  • Thank you Mason. I hope I'm not overstepping but is it possible to show me how I would adjust my code accordingly? I understand what you're saying and I'm just having trouble implementing it. Other than that, your help is much appreciated. Thank you – Mavric Apr 10 '17 at 13:29
  • You have an EF DB Context in your controller? You know how to retrieve an entity from it by ID? – mason Apr 10 '17 at 13:29
  • I think you've made a mistake trying to use EF here. Are you familiar with SQL? Insert, update, delete, select etc? – mason Apr 10 '17 at 13:30

0 Answers0