0

With the help of several SO questions, I've figured out how to use two models on the same view, using the tuple form. At the top of my file is this:

@using Project.Models;
@{
    ViewBag.Title = "Details";
    Layout = "~/Views/Shared/_Layout.cshtml";
    @model Tuple<Foo, Bar>
}

For the Foo stuff, it uses jQuery like this:

@Html.DisplayFor(tuple => tuple.Item1.ID)

and works fine. However, for my second model, it isn't displaying info, but is a submission form. Currently, this is what I have:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "createFoo", @action = "/api/Foo" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

    <div class="editor-field">
        @Html.TextAreaFor(tuple => tuple.Item2.Text)
        @Html.ValidationMessageFor(tuple => tuple.Item2.Text)<br />
    </div>

    <input type="submit" value="Post Response" />
}

Mind you, this is mostly copy paste from other views since I'm new to MVC and it worked fine with other forms. For my FooController, I have this:

public void Post([FromBody] Foo foo)
        {
            Foo existingFoo = this.fooRepository.GetFoo(foo.ID);
            if (existingFoo != null)
            {
                // throw error
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("MESSAGE POSTING: " + foo.Text);
            }
        }

When submitting from the view, the received foo isn't null (checked in other tests), but the foo.text is empty. I've tried lots of different inputs and such, but I'm just so unfamiliar with the @Html.* functions and ASP.net-MVC in general that I'm not sure where I could be going wrong.

If you need to see my repository code let me know, but I doubt it'd have an effect on this. Thanks in advance for any help.

Simon C
  • 9,458
  • 3
  • 36
  • 55
Befall
  • 6,560
  • 9
  • 24
  • 29
  • 1
    You do realize that MVC and Web API are two completely different frameworks and you can't mix-and-match attributes from one in the other... right? API actions aren't designed for forms, they're designed to accept JSON or XML or something similar; if you want to deal with POST data, you have to [hack around it](http://stackoverflow.com/questions/17832784/how-to-get-post-data-in-webapi). – Aaronaught Mar 14 '14 at 01:20
  • @Aaronaught: I vaguely knew, but I'm still very, very new to this framework, so a lot of things are still mysterious to me. Thanks for the link, it's useful as are the other resources on it. – Befall Mar 14 '14 at 14:36

1 Answers1

2

There are 2 issues I can see with your code above:

  1. The way the Html helper will output your fields and how that feeds into your api post
  2. Not having your ID in the controller.

1: Outputting a field like this (@Html.TextAreaFor(tuple => tuple.Item2.Text)) will give the field the name "Item2.Text". This is an issue as that is what gets passed on the post. You will get form data with Item2.Text:dfsdsgdfg. This won't match when your API controller tries to bind. So, try outputting the text field with a set name:

@Html.TextArea("Text", @Model.Item2.Text)

2: Your Id field is not in the form... thus it won't be sent. Try using a hidden field:

@Html.Hidden("ID", @Model.Item1.ID)

Also, just a clarification, this (@Html.DisplayFor(tuple => tuple.Item1.ID)) is not jQuery.

Simon C
  • 9,458
  • 3
  • 36
  • 55
  • Thank you so much, it worked. However, I don't like feeling confused about the @Html stuff, do you have a good link explaining your comments regarding what Html.TextAreaFor returns and how it's different from Html.TextArea. As Aaronaught mentioned, I know it's finding a hack to interact between the two frameworks, so the more I know, the easier it'll be. Thanks again, mate. – Befall Mar 14 '14 at 14:36
  • Here is a link discussing the differences with the different Html helpers: http://stackoverflow.com/questions/5908523/html-textbox-vs-html-textboxfor. Essentially there is no great difference and I suspect that the `For` method calls the other one under the hood. It's two different ways to get very similar HTML output. In your case it's just easier to use the `Html.TextArea` helper method. – Simon C Mar 16 '14 at 21:11
  • As for mixing MVC and WebAPI, I think what you're doing is fine, and WebAPI supports `application/x-www-form-urlencoded` content out of the box. It's easiest to use sending complex types (which you are). – Simon C Mar 16 '14 at 21:17