umki
umki

Reputation: 779

Asp.net MVC C# One Form, Two Model

I have two models like below.

 public class Bill
    {
        public int Id { get; set; }
        public string InvoiceNumber { get; set; }
        public Int64 Amount { get; set; }
        public int? NewPaymentId { get; set; }
        public virtual NewPayment RelPayment { get; set; }
    }


 public class NewPayment
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LstName { get; set; }    
        public DateTime PaymentDate { get; set; }
        public Int64 ProvisionNumber { get; set; }
        public Int64 CreditCardNumber { get; set; }
        public int ExpMonth { get; set; }
        public int ExpYear { get; set; }
        public int Cv2 { get; set; }
        public Int64 Amount { get; set; }
        public string UserId { get; set; }
        public string CustomerNote { get; set; }

    }

Customer is going to pay his invoices via credit card in my application.

I had one view which i posted the NewPayment model to the action. But now, i need to send also which invoices will be paid. So i need to create one more form for the Bill model i think ? But i cant figure out how can i pass two model to same action and i dont know the NewPaymentId before executing the payment method.

REGARDING TO THE COMMENTS :

My combine model as below :

public class Payment
{
    public IEnumerable<Bill> Bill { get; set; }
    public NewPayment NewPayment { get; set; }
}

And my view as below :

@model IEnumerable<ModulericaV1.Models.Bill>
  <form class="form-no-horizontal-spacing" id="NewPayment" action="/NewPayment/AddInvoice" method="post">
                <div class="row column-seperation">
                    <div class="col-md-6">
                        <h4>Kart Bilgileri</h4>
                        <div class="row form-row">
                            <div class="col-md-5">
                                <input name="FirstName" id="FirstName" type="text" class="form-control" placeholder="Kart Üzerindeki Ad">
                            </div>
                            <div class="col-md-7">
                                <input name="LastName" id="LastName" type="text" class="form-control" placeholder="Kart Üzerindeki Soyad">
                            </div>
                        </div>
                        <div class="row form-row">
                            <div class="col-md-12">
                                <input name="CreditCardNumber" id="CreditCardNumber" type="text" class="form-control" placeholder="Kart Numarası">
                            </div>
                        </div>
                        <div class="row form-row">
                            <div class="col-md-5">
                                <input name="ExpYear" id="ExpYear" type="text" class="form-control" placeholder="Son Kullanma Yıl (20..)">
                            </div>
                            <div class="col-md-7">
                                <input name="ExpMonth" id="ExpMonth" type="text" class="form-control" placeholder="Son Kullanma Ay (1-12)">
                            </div>
                        </div>

                        <div class="row form-row">
                            <div class="col-md-5">
                                <input name="Cv2" id="Cv2" type="text" class="form-control" placeholder="Cv2">
                            </div>
                            <div class="col-md-7">
                                <input name="Amount" id="Amount" type="text" class="form-control" placeholder="Miktar TL ">
                            </div>
                        </div>


                        <div id="container">
                            <input id="Interests_0__Id" type="hidden" value="" class="iHidden" name="Interests[0].Id"><input type="text" id="InvoiceNumber_0__InvoiceNumber" name="[0].InvoiceNumber"><input type="text" id="Interests_0__InterestText" name="[0].Amount"> <br><input id="Interests_1__Id" type="hidden" value="" class="iHidden" name="Interests[1].Id"><input type="text" id="InvoiceNumber_1__InvoiceNumber" name="[1].InvoiceNumber"><input type="text" id="Interests_1__InterestText" name="[1].Amount"> <br>
                        </div>
                        <input type="button" id="btnAdd" value="Add New Item" />

                        <button class="btn btn-danger btn-cons" type="submit"> Ödemeyi Gerçekleştir</button>
        </form>
    </div>
</div>

In my controller, i am getting payment model as null.

public ActionResult AddInvoice(Payment payment) {

            foreach (var item in payment.Bill)
            {
                var Billing = new Bill();
                Billing.Amount = item.Amount;
                Billing.InvoiceNumber = item.InvoiceNumber;
                db.Bill.Add(Billing);
                db.SaveChanges();
            }

            return View();
        }

    }

Upvotes: 0

Views: 1579

Answers (4)

Kind Contributor
Kind Contributor

Reputation: 18543

You appear to already have the solution in your model. Your bill object can hold a reference to a related new payment. You can either lazy read the new payment from database or you could assign a new newpayment object to the bill before sending to the view.

View models are good practice, but you might be happy levering the model you have naturally as I just described.

Update

Sorry, this should be:

  1. The other way around - Pass in NewPayment
  2. Add public IEnumarable<Bill> Bills {get; set;} to NewPayment model

And that way, you can access the Bills associated with the given payment.

Code first stuff:

  • You should decorate Bill's RelPayment with [ForeignKey("NewPaymentID"], so EF (I assume you are using Entity Framework), knows how to wire up the relationship.
  • You will also likely need to add the following Bills = new List<Bill>(); into a NewPayment constructor.

Upvotes: 0

Nic
Nic

Reputation: 1089

If you don't like Zakos Solution you can make tuple :

var tuple= new Tuple<Bill,NewPayment>(obj1,obj2);

And in view you will have :

@model  Tuple<Bill,NewPayment>

But you should use @Zakos solution.

Upvotes: 0

Ehsan
Ehsan

Reputation: 834

So you can use ViewModel, take this ViewModel:

public class PaymentBillViewModel
    {
        public int BillId { get; set; }
        public int PaymentId { get; set; }
        public string InvoiceNumber { get; set; }
        public Int64 Amount { get; set; }
        public int? NewPaymentId { get; set; }
        public virtual NewPayment RelPayment { get; set; }
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LstName { get; set; }    
        public DateTime PaymentDate { get; set; }
        public Int64 ProvisionNumber { get; set; }
        public Int64 CreditCardNumber { get; set; }
        public int ExpMonth { get; set; }
        public int ExpYear { get; set; }
        public int Cv2 { get; set; }
        public Int64 Amount { get; set; }
        public string UserId { get; set; }
        public string CustomerNote { get; set; }

    }

actually put what you need in your View. then in the post action cast the ViewModel to the related Model:

[HttpPost]
        public ActionResult Sample(PaymentBillViewModel model)
        {
            if (ModelState.IsValid)
            {
               var obj=new NewPayment
               {
                   LstName= model.LstName,
                   Amount=model.Amount,
                   //... cast what else you need
               }
            }
            return View();
        }

you can use Automapper on casting, for more info about using Automapper take a look at this article.

Upvotes: -1

Zakos
Zakos

Reputation: 1509

i complete Marko with an example

public class CombineModel
{
   public Bill Bill{ get; set; }
   public NewPayment NewPayment{ get; set; }
}

Upvotes: 5

Related Questions