0

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();
        }

    }
3
  • 3
    You cannot pass two models. But what you can do is combine your two models into one model and pass that model to your action and then decide what to do with it in your business logic or controller. Commented Mar 9, 2014 at 13:19
  • I dont understand actually, there will be one more than invoice and one payment for all of them. Commented Mar 9, 2014 at 13:22
  • 1
    See Zakos answer bellow... Commented Mar 9, 2014 at 13:25

4 Answers 4

5

i complete Marko with an example

public class CombineModel
{
   public Bill Bill{ get; set; }
   public NewPayment NewPayment{ get; set; }
}
Sign up to request clarification or add additional context in comments.

8 Comments

What if i want to pass more than one Bill object ? Need i change to IEnumerable ?
IEnumerable , List , w/e make you happy
Ok i have created my class with public IEnumerable<Bill> Bill { get; set; } But i could not figure out how can i pass the values to the action method ?? Should i need to create two form, or while i dont have any NewPayment object and ID , how can i assign the invoices to the NewPayment object which will be created after click the submit button ?
well this question is "out of the scope" of this question , google how to bind model to the view in asp mvc , it seems the concept of mvc bindings is still new to you . In nutshell , it all depends how you wanna do it , but If I understand you , after submit button has been pressed , CombineModel model is back to your controller method with the input-values ( if the binding is correctly) , now your controller is the LOGIC , do w/e you need to do , you can save NewPayment into into the DB , and then bind the ID of it into bill[x].NewPaymentId . I hope this gives u a direction.
another thing , make your you encrypt NewPayment somehow , or any other security , cuz u pass a Credit Card number here...
|
0

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.

3 Comments

But there wil be more than one invoice per payment.
@ukmi - I think my answer still stands. I have updated it to fix my misunderstanding though.
I see, I misunderstood your problem, I didn't realise that you were posting from the client to controller, I assumed it was the other way around - silly me. I will delete this answer.
0

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.

Comments

-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.