1

In ASP.NET MVC (5.x, not Core), I have a CSHTML page where the model contains a nested object for which I have input controls, similar to:

@Html.TextBoxFor(model => model.Order.CustomerName)

Done that way, ASP.NET prefixes the id and name attributes of the input tag with "Order", per:

<input id="Order_CustomerName" name="Order.CustomerName" type="text" value="...">

The prefixes mess up the form post. I can force the name and id to be just CustomerName by doing:

@Html.TextBoxFor(model => model.Order.CustomerName, new { id = "CustomerName", name = "CustomerName" })

but that's a nuisance to have to do that on every input control.

I could move all the input fields into a partial and invoke it with Model.Order as its model, but splitting out the content has some gotchas in my scenario.

Is there a way to specify to use Model.Order as the model for all controls within a form or a section of a page? Something like the following fictional directive:

@useModel(Model.Order) {
    @Html.TextBoxFor(model => model.CustomerName)
}
user221592
  • 361
  • 1
  • 10
  • What do you mean by 'The prefixes mess up the form post' ??? – Adlorem Aug 06 '20 at 19:24
  • @Adlorem The snippet I showed above is within a form which posts to an endpoint which takes just an Order as a parameter. Since the post uses the name attribute of the input elements, all the fields are prefixed with "Order." thus ASP.NET fails to reconstruct the Order object. – user221592 Aug 07 '20 at 22:05
  • [Related question](https://stackoverflow.com/q/18595565/1178314), could help when using an editor template. – Frédéric Aug 16 '21 at 12:28

1 Answers1

1

Based on you comments you are trying to pass complex model from view to controller. This works perfectly fine, but you have to specify in controller what to expect. Lets say you have model

public class Purchase
{
    public Order Order { get; set; }
}

You tell razor to render field for Order => CustomerName

@Html.TextBoxFor(model => model.Order.CustomerName)

In you html form you got it rendered as:

<input id="Order_CustomerName" ...>

Now when posting to controller you have to tell controller how to process request so:

public ActionResult RegisterPurchase([Bind(Prefix = "Order")]Order objOrder)
{
}

If you just add to your controller

public ActionResult RegisterPurchase(Purchase objPurchase)
{
}

Your Order object gonna be null.

Adlorem
  • 1,457
  • 1
  • 11
  • 10