MVC manually serialize complex object or model binding

One of the biggest problems I run into in MVC is when I attach a complex property (view model) to my model for use on a form. For example, I have a Customer.cs model. This Customer has (for simplicity) 1 order at any time. So I give it the Customer.Order property. A Client has many other properties that define it as a unique client. The Order property has a set of unique properties. So Im rolling forward, building my controller, other model values, and finally I start working out my details.
I start by defining the Form itself.

@using (Html.BeginForm("Customer", "Home", FormMethod.Post, new { @id = "customerForm" })

      

This form declaration basically tells the View that when the user clicks the submit button, everything in that form should be serialized and submitted to the controller. First, I create a view for my main Customer.cshtml model. It takes a Customer.cs model.

I am creating a view specifically for this complex object I've created called Order.cshtml. It accepts an Order.cs model (so I can reuse it later in other parent models like Invoice because I'm smart and think ahead.) So I wrote all this javascript and view logic that depends on what the view is independent and reusable with other models. My ad text boxes look like this:

@Html.TextBoxFor(m => m. OrderDate) 

      

When I go to the Submit button, the first thing I notice is that none of the Order object values ​​have been sent back. So I sit and debug and it takes a while, but I finally figured out that this would not work. If theres doesn't allow you to serialize the view model separately and then attach it to the parent model, even then you'll have to write a bunch of Javascript to manually override the default submit process as well as any other model you can do for the client-side field validation.
I think there must be an easier way to handle this. I know a way around this problem, but its not really. You can create a view for Order.cs to take the Customer.cs model instead. Then use text boxes for declarations like this:

@Html.TextBoxFor(m => m.Order.OrderDate) 

      

To define all properties in the view. This will work with the default binding and it will be fine. Also, what about the code I've already written in JavaScript? The ID must go through and add "Order_" to all ID links posted in the form. Also, now it doesn't move easily between models, Id have to recreate this view every time I create a new model that uses the Order object since it now accepts a Customer.cs model. Id also have to rewrite the javascript or come up with some fancy way to pass the (ViewData) prefix. It doesn't seem right. What am I doing wrong?

+3


source to share


1 answer


What if you create an interface for all view models that use Order:

interface IWithOrder
{
    Order Order { get; set; }
}

      

Use this interface in a generic Order view:

@model Project.ViewModels.IWithOrder
...
@Html.TextBoxFor(m => m.Order.OrderDate, new { Id = "OrderDate" }) 

      



In the case of the Client, you can create a client view model that is sourced from IWithOrder:

public class CustomerViewModel : IWithOrder
{
    public Order Order { get; set; }

    public Customer Customer { get; set; }
}

      

You can now reuse the view Order

, but your viewmodels should be retrieved from the IWithOrder.

You can also set id of html elements in parameter htmlAttributes

TextBoxFor

if you don't want to add Order_

js in links.

+1


source







All Articles