title: Ajax POST works with [FromForm] but not with [FromBody]
body: <p>In my View I pass <code>BookViewModel</code> and I have a form which I am trying to create a <code>Book</code> with. I can perform this if I use the <code>[FromForm]</code> attribute but I am trying to understand how that differs from <code>[FromBody]</code>. Here are my models:</p>
  <pre><code>public class Book
  {
      public int Id { get; set; }
      public string Title { get; set; }
      public int GenreId { get; set; }    //foreign key from Genre
  
      public virtual Genre Genre { get; set; }
  }
  
  public class BookViewModel
  {
      public ICollection&lt;Book&gt; Books { get; set; }
      public Book Book { get; set; }
  }
  </code></pre>
  <p>Here is my View and Controller:</p>
  <pre><code>[HttpGet]
  public IActionResult Index()
  {
      BookViewModel books = new BookViewModel
      {
          Books = _context.Books.Include(x =&gt; x.Genre).ToList()
      };  // _context.Books is my database context and table
  
      return View();
  }
  
  [HttpPost]
  [ValidateAntiForgeryToken]
  public IActionResult Index([FromForm] BookViewModel b)  //works without
  {                                                       //[FromForm] too
      //code to perform tasks
      //etc
      //return Json(true);      The parameters work fine but I would like [FromBody]
  }
  </code></pre>
  <p>View:</p>
  <pre><code>&lt;form id=&quot;formid&quot; method=&quot;post&quot;&gt;
      &lt;div asp-validation-summary=&quot;ModelOnly&quot;&gt;&lt;/div&gt;
  
      &lt;label&gt;Title&lt;/label&gt;
      &lt;input asp-for=&quot;Book.Title&quot; class=&quot;form-control&quot; /&gt;
      &lt;span asp-validation-for=&quot;Book.Title&quot;&gt;&lt;/span&gt;
  
      &lt;label&gt;Genre&lt;/label&gt;
      &lt;input asp-for=&quot;Book.GenreId&quot; class=&quot;form-control&quot; /&gt;
      &lt;span asp-validation-for=&quot;Book.GenreId&quot;&gt;&lt;/span&gt;
  
      &lt;button type=&quot;button&quot; onclick=&quot;SaveData()&quot;&gt;Submit&lt;/button&gt;
  &lt;/form&gt;
  
  &lt;script&gt;
      function SaveData(){
          event.preventDefault();
          var formData = $(&quot;#formid&quot;).serialize();
  
          $.ajax({
              url: &quot;/&quot;,
              type: &quot;POST&quot;,
              data: formData,
              beforeSend: function(request){
                    request.setRequestHeader(
                    &quot;RequestVerificationToken&quot;, 
                         $(&quot;[name=__RequestVerificationToken']&quot;).val());
              }
           });
       }
  &lt;/script&gt;
  </code></pre>
  <p>All of this code works fine but I would like to use <code>[FromBody]</code> instead.</p>
  <p>I have added <code>contentType: &quot;application/json&quot;</code> to my ajax, and added <code>[FromBody]</code> to my action method, but when I submit my form, <code>BookViewModel</code> is null in the action method. I would like to know how I could submit my form with <code>[FromBody]</code> with <code>contentType: &quot;application/json&quot;</code> instead of <code>application/x-www-url-formencoded</code>?</p>
  <p><code>[FromBody]</code> will perform default model binding which is what I want here. I am assuming that the reason <code>[FromBody]</code> has not worked is because of the way I am serializing the form but I am not sure.</p>