-1

I'm just trying to get some simple model binding to work!

My model, defined using Entity Framework, has a property named "Note".

public partial class ContractNote
{
    public short Id { get; set; }
    public short ContractId { get; set; }
    public System.DateTime Date { get; set; }
    public string Note { get; set; }
    public Nullable<System.DateTime> CompletionDate { get; set; }
    public bool Completed { get; set; }
 }

I'm using an Ajax call to post the updated data back from a modal form on the web page.

        $.ajax({
        url: '@urlHelper.Action("EditNote", "Contracts")',
        type: "POST",
        contentType: "application/json;charset=utf-8",
        data: JSON.stringify({ Id: noteId, ContractId: contractId, Date: date, Note: note, CompletionDate: cdate, Completed: completed }),
        success: function (data) {
            switch (data.status) {
                case "error":
                    alert(data.message);
                    break;
                default:
                    Refresh(model.notes);
                    break;
            }
        },

And the controller action tries to bind to a ContractNote object.

public JsonResult EditNote(ContractNote note)
{ .... }

I cannot get this to work - the bound object "note" is always null. I found I could post all of the fields OK, except for "Note". If I leave this out it binds OK.

Moreover, I created a dummy class in my code, exactly the same as ContractNote, but with the property "Note" renamed to "xyz".

public class ContractNoteJSON
{
    public short Id { get; set; }
    public short ContractId { get; set; }
    public System.DateTime Date { get; set; }
    public string xyz { get; set; }
    public Nullable<System.DateTime> CompletionDate { get; set; }
    public bool Completed { get; set; }
}

And I updated my controller and Ajax code accordingly.

Incredibly, this binds perfectly! So it would seem that the MVC model binder has problems with a field named "Note" specifically.

Can someone confirm this is the case? Is there a way I can work around this? I am able to change database and EF to give it a different name, but I'd rather not and I'm curious to find out whether some simple mapping can be done.

Thanks in advance

Doug

Doug
  • 457
  • 5
  • 17
  • What happens if you leave your property named Note and change your javascript variable name from note to something else? I'm just curious as this seems like strange behavior. – Ryan Wilson Feb 23 '18 at 16:39
  • Another question, why are you using JSON.stringify when you are passing in a custom model object? What if you changed your ajax data to this: data: { Id: noteId, ContractId: contractId, Date: date, Note: note, CompletionDate: cdate, Completed: completed }, – Ryan Wilson Feb 23 '18 at 16:42
  • Not related, but remove `contentType: "application/json;charset=utf-8",` and just use `data $(yourForm).serialize(),` assuming you have generated the form correctly –  Feb 23 '18 at 21:11
  • Ryan. Thanks for your reply. As expected, if I rename the javascript parameter it doesn't get bound. So the object created by the binding has it's property Note set to null. This fails when EF tries to save the object as Note is required. – Doug Feb 25 '18 at 20:21
  • Ryan/Stephen. Yes, I found I didn't need to use JSON stringify once I removed contentType: "application/json;charset=utf-8" . I'm not using a form as such. I'm just lifting values from elements using jQuery and using the values in the ajax call. Many thanks. – Doug Feb 25 '18 at 20:27

1 Answers1

1

I believe you need to rename your action parameter:

public JsonResult EditNote(ContractNote postedNote)

What must be happening is model binding trying to match value of the posted note parameter to action method parameter of type ContractNote, just because they have the same name. This of course fails as posted value is just a string. Renaming method parameter should resolve the confusion.

Andrei
  • 55,890
  • 9
  • 87
  • 108