Question

I have a simple form for modifying part of a complex model. I can of course pare down the model, but I would like to solve the complex case, because we'll eventually be dealing with the whole model anyways.

I want the rendered input to have a simple Id and Name, but the model name seems to be unmovable.

@Html.EditorFor(model => model.CallInfo.Phone1,
   new { @id = "Phone1", @name = "Phone1"})

Should output this

<input type="text" value="" name="Phone1" id="Phone1" class="text-box single-line">

Instead, it outputs this, with CallInfo prefixed everywhere.

<input type="text" value="" name="CallInfo.Phone1" id="CallInfo_Phone1" class="text-box single-line">

If this can't be defeated, then is there a way to get the CallInfo.Phone1 parameter to auto-parse into a parameter for the action method? Because this is waaay invalid syntax in C#.

public ActionResult UpdatePhoneNumber(Int32 profileId, String CallInfo.Phone1)

Again, I realize I could manually retrieve it from the request, like so

HttpRequest.Current.Params["CallInfo.Phone1"]

But it really seems like the C# MVC4 conventions should play nice together here, making ONE of these auto-magic widgets do the right thing.

Update: Following Dmitri's answer, I left the view markup the way it was, with the name="CallInfo.Phone1" attribute as generated and modified the action signature to this:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdatePhoneNumber(Int32 profileId,
    [Bind(Prefix = "CallInfo")] string phone1)
{
    // Save it
}

In the debugger, phone1 is null and does not get saved to the database. The post body, captured from firebug, has this to say:

Parameters          application/x-www-form-urlencoded
CallInfo.Phone1     8121234567

I've also tried capitalizing the p in the Phone1 parameter name to no effect.

Was it helpful?

Solution

If this can't be defeated, then is there a way to get the CallInfo.Phone1 parameter to auto-parse into a parameter for the action method? Because this is waaay invalid syntax in C#.

Sure, using the [Bind] attribute:

public ActionResult UpdatePhoneNumber(
    int profileId, 
    [Bind(Prefix = "CallInfo")] string phone1
)
{
    ...
}

or even better, by defining a view model:

public class MyViewModel
{
    public int ProfileId { get; set; }
    public CallInfoViewModel CallInfo { get; set; }
}

public class CallInfoViewModel
{
    public string Phone1 { get; set; }
}

and then having your controller action take this view model as argument:

public ActionResult UpdatePhoneNumber(MyViewModel model)
{
    ...
}

OTHER TIPS

If I understand you right, you want CallInfo.Phone1 and Phone1 as arguments to the Action Method. In that case your Model should be a container for a CallInfo Model and Phone1 (string?) param.

class bigModel
{
   CallInfoType CallInfo { get;set;}
   string Phone1 { get;set;}

}

Pass the same model to your view

@model Project.Models.bigModel

and use it in signature of your action method

    public ActionResult Edit(bigModel);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top