Reputation: 863
I'm new to ASP.NET Core and I'm trying to post a view model to my controller (I think).
Model:
public class ToolModel
{
public ToolModel() { }
public string text { get; set; }
public string type { get; set; }
public string name { get; set; }
}
Controller
[HttpPost("/Utilities/Tool/{type}/{process}")]
public IActionResult ToolProcess(ToolModel model, string type, string process)
{
var test = model.text;
var result = new Services.ToolServices().exec(model, type, process);
return Ok(result);
}
View
var model = {
text: "Test_text",
type: "test",
name: "test_name"
}
function post(model) {
var url = '/Utilities/Tool/Test/Edit';
$.ajax({
url: url,
data: JSON.stringify(model),
type: 'POST',
success: function () {
alert("all good");
},
error: function () {
alert(":(");
}
});
}
I'm currently able to get to a break point within my controller but the model value is null. I've tried various combinations of this process, including adding [FromBody] to the controller arguments. When I add [FromBody] I don't reach my breakpoint at all, the request just fails, and I get the error: "No element found".
At first I tried passing my ToolModel model to my view in my index controller, but I couldn't figure out how to connect the data from my view to the Model (I tried setting @Model.text = "test" without success). That didn't work, so I just replicated the model as a javascript object. Based on what I've read, it's supposed to automatically bind to my model when I post the json?
I'm so new to ASP.NET Core that I don't even know what to google, and every variation of the post fails for me. How do I get data from my view to my controller, using my model, via ajax? Everyone seems to do it differently.
Upvotes: 0
Views: 5469
Reputation: 218862
Since you are sending the data via POST request, the data will be send in the request body. So you should instruct MVC framework to read it from the request body. You can decorate your parameter with the [FromBody]
attribute to do that.
Also, remove the type
parameter as your ToolModel class has a property with the same name. You may remove it from your attribute route definition as well.
[HttpPost("/Utilities/Tool/{process}")]
public IActionResult ToolProcess([FromBody] ToolModel model, string process)
{
var test = model.text;
var result = model;
// to do : Add your custom code here
return Ok(result);
}
On the clent side, you need to specify the contetType header so server know what the type it is receiving and how to process it. Specify "application/json" as the contentType value in your ajax call.
var url = '/Utilities/Tool/Edit';
$.ajax({
url: url,
data: JSON.stringify(model),
contentType:"application/json",
type: 'POST',
success: function (r) {
alert("all good");
console.log(JSON.stringify(r));
},
error: function () {
console.log('errr');
}
});
Upvotes: 6
Reputation: 62300
What I see is you have model as parameter in the post function. If you do not provide it, it'll be null.
Ideally, you do not need to /Test/Edit
in URL, since they will be inside the body already.
Here is how I tested -
<button type="button" onclick="post();">Post Data</button>
<script>
var model = {
text: "Test_text",
type: "test",
name: "test_name"
}
function post() {
var url = '/Utilities/Tool';
$.ajax({
url: url,
data: JSON.stringify(model),
type: 'POST',
contentType: "application/json",
success: function() {
alert("all good");
},
error: function() {
alert(":(");
}
});
}
</script>
[HttpPost("/Utilities/Tool")]
public IActionResult ToolProcess([FromBody]ToolModel model)
{
model.text += "Return From Server";
return Ok(model);
}
Upvotes: 1