0

I have a complex form with different tabs, so my ask is to save the entire form data to database on final save. I have the models as per my database as follows, posting sample class

public class VesselDetail
{
   public string VesselName { get; set; }
}

public class MainModel
{
   public VesselDetail VesselDetail { get; set; }
}

I have created JavaScript models as follows

class VesselDetail {
    constructor() {

    }
    VesselName;
}
class MainModel {
   constructor() {
    this.VesselDetail = [];
   }
}

On my save I am framing the data as follows

 let data = new MainModel();
 let vesselDetail = new VesselDetail();
 vesselDetail.VesselName = "XYZ";
 data.VesselDetail.push(vesselDetail);
 
 $.ajax({
    url: '/Controller/SaveFormData',
    type: 'POST',
    data: '{mainModel: ' + JSON.stringify(data) + '}',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (result) {
        hideSpinner();
    },
    error: function (request) {
        hideSpinner();
    }
});

My controller is as follows

[HttpPost]
public JsonResult PostUserData(MainModel mainModel)
{
   return new JsonResult { Data = "OK" };
}

Somehow I am unable to see the vessel name that was given. I would like to know are my JavaScript models are correct or should I do any changes? Any better idea to make these models in JavaScript.

3 Answers 3

2

Don't hand-construct JSON, it's really easy to get it wrong. In this case, you haven't put the necessary " around mainModel in the JSON you're sending the server, which makes it invalid. As a result, the server won't be able to parse the JSON it receives.

 $.ajax({
    url: '/Controller/SaveFormData',
    type: 'POST',
    data: '{mainModel: ' + JSON.stringify(data) + '}',
//          ^−−−−−−−−^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− missing quotes
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (result) {
        hideSpinner();
    },
    error: function (request) {
        hideSpinner();
    }
});

Instead, let JSON.stringify do it for you:

 $.ajax({
    url: '/Controller/SaveFormData',
    type: 'POST',
    data: JSON.stringify({mainModel: data}),
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (result) {
        hideSpinner();
    },
    error: function (request) {
        hideSpinner();
    }
});

Also, unless your server is returning JSON you're not using, you don't need dataType. (Even if it is, it should be returning the correct Content-Type header in which case dataType is redundant anyway.)

I also suggest either consistently using property declaration syntax (which is fairly new) or consistently not using it:

Not using it:

class VesselDetail {
}

class MainModel {
    constructor() {
        this.VesselDetail = [];
    }
}

Using it:

class VesselDetail {
    VesselName;
}

class MainModel {
    VesselDetail = [];
}

Here's an example of the JSON that will be produced by your code with the changes above (I've used property declaration syntax — the second set of classes above — but they'll both produce the same thing):

class VesselDetail {
    VesselName;
}

class MainModel {
    VesselDetail = [];
}

let data = new MainModel();
let vesselDetail = new VesselDetail();
vesselDetail.VesselName = "XYZ";
data.VesselDetail.push(vesselDetail);
const json = JSON.stringify({mainModel: data});

console.log(json);

As you can see, VesselName is not blank.

Sign up to request clarification or add additional context in comments.

4 Comments

Is it mandatory to have constructor? I have so many fields
I am still getting the VesselName as empty
@Developer - No, it isn't mandatory. You can do it the way you're doing it in the question as well. I thought it was just the one field. (I've removed that part of the answer.) The code above definitely produces valid JSON containing a non-blank VesselName. If you're getting a blank one on the server, either the JavaScript code you're using isn't filling in VesselName or the server code isn't looking for it in the right place.
On the client side I can see but in my MVC controller I couldn't
1

try this, it was tested in VS2019 and working properly

var mainModel= { VesselDetail : { VesselName :"XYZ"} };
  
 $.ajax({
    url: '/Controller/PostUserData',
    type: 'POST',
    data: { mainModel: mainModel),
    success: function (result) {
        hideSpinner();

        alert(JSON.stringify(result));
    },
    error: function (request) {
        hideSpinner();
 
    }
});

and fix VesselDetail class by adding setter and getter

public class VesselDetail
{
   public string VesselName { get; set;}
}

And I see a bug in your action. What is a Data?

return new JsonResult { Data = "OK" };

try this

return  new JsonResult(mainModel.VesselDetail.VesselName);

but if you like it a hard way you can try this

class VesselDetail {
VesselName;
}

class MainModel {
VesselDetail = {};
}

let mainModel= new MainModel();
data.VesselDetail.VesselName="XYZ";

UPDATE

Sometimes this working better, depending on net version or if you are using API controller

var mainModel= { VesselDetail : { VesselName :"XYZ"} };
  
 $.ajax({
    url: '/Controller/PostUserData',
    type: 'POST',
    data: JSON.stringify(mainModel),
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (result) {
        hideSpinner();
    
        alert(JSON.stringify(result));
    },
    error: function (request) {
        hideSpinner();
    }
});

but you have to add [FromBody] to action

[HttpPost]
public JsonResult PostUserData([FromBody] MainModel mainModel)
{
   return  new JsonResult(mainModel.VesselDetail.VesselName);
}

23 Comments

I have already get;set; how was your controller code looks like?
Getting 500 error can I get the controller?
@Developer What is your controller name?, you will have to replace "Controller" with it
Is your controller looks like this [HttpPost] public JsonResult PostUserData(MainModel mainModel) { return new JsonResult { Data = "OK" }; }
I am checking at MainModel to see if VesselName coming
|
-1

you put the VesselName out of the builder

should be like this

class VesselDetail {
constructor() {
    this.VesselName;
  }
}

class MainModel {
constructor() {
    this.VesselDetail = [];
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.