First off I am learning Asp.net core. I have a View as follows, when I the blogItemId I retrieve an item and send it as a model to the DetailedView.cshtml
as follows:
[HttpGet]
public IActionResult DetailedView(int blogItemId)
{
var item = _mainBlogHelperModel.BlogDataItems.FirstOrDefault(x => x.Id == blogItemId);
if (item == null)
{
return RedirectToAction("MainBlog", new { page = 1, blogCategory = "" });
}
return View(item);
}
Now in the DetailedView.cshtml
, I have a form. When I click the "Post Comment" button within the form, I would like to save some model record within the database and update some section with in the view.
Problem number 1: Please see my Model class below, I have a navigation property and foreign key. How do I specify these values within jQuery from my Model.
Problem number 2: I have a breakpoint in the PostComment
method, but jQuery is not binding any values. Everything is null. please help.
Here is my DetailedView.cshtml
:
@model KGSBlog.Models.BlogData
@SOME CODE HERE @
<form id="formPostComment" method="post" action="BlogData/PostComment">
<div class="row">
<div class="col-md-6">
<input type="text" placeholder="Name *" id="name" name="name">
</div>
<div class="col-md-6">
<input type="email" placeholder="Email *" id="email" name="email">
</div>
</div>
<div class="row">
<div class="col-xs-12">
<input type="text" placeholder="WebSite" name="website">
</div>
</div>
<textarea name="message" placeholder="Message *" id="message" cols="45" rows="10"></textarea>
<button id="btnPostComment" class="btn btn-main m-bottom-40">Post Comment</button>
</form>
@section Scripts {
<!-- jQuery -->
<script src="~/js/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="~/bootstrap/js/bootstrap.min.js"></script>
<!-- Components Plugin -->
<script src="~/js/jquery.easing.1.3.js"></script>
<script type="text/javascript">
$(function () {
$("#btnPostComment").click(function () {
var name = $("#name").val();
var email = $("#email").val();
var message = $("#message").val();
var dataToPost = {};
dataToPost.Name = name;
dataToPost.Email = email;
dataToPost.Comment = message;
//How can I populate the BlogId and Blog properties here?
$.ajax({
url: '@Url.Action("PostComment", "BlogData")',
data: JSON.stringify(dataToPost),
type: "POST",
dataType: 'JSON',
contentType: "application/json",
success: function(data) {
//do stuff with json result
},
error: function(passParams) {
console.log("Error is " + passParams);
}
});
});
});
</script>
}
Here is my BlogDataController
PostComment
action method where the properties in the blogComment
parameter are all null.
[HttpPost]
public async Task<IActionResult> PostComment(BlogComments blogComment)
{
if (blogComment != null)
{
await _context.BlogComments.AddAsync(blogComment);
await _context.SaveChangesAsync();
}
var item = _mainBlogHelperModel.BlogDataItems.FirstOrDefault(x => x.Id == blogComment.Id);
return new JsonResult(new { comment = blogComment.Comment, name = blogComment.Name });
}
The BlogComments
model class
public class BlogComments
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Comment { get; set; }
[ForeignKey("BlogID")]
public int BlogId { get; set; }
public BlogData Blog { get; set; }
}
3
Answers
I don't know whats the difference between what I wrote and this, except for some attributes, but i changed the jquery code as follows, after referring to this post and it works. If someone can tell me why my old code was not working and this one is working, that will be great. (May be I shouldn't stringify the object)
First off I made the form like this,
The Controller code, I just changed the parameter like this. Even with the old jquery code, I tried Bind like this and it didn't work.
Problem number 1: Ideally, you don’t want to pass the
Blog
property, you just want to pass theBlogId
. It’s not causing your issue but in my opinion, you shouldn’t use the entity as the model, you should have another class that acts as a DTO. Is it good practice to use entity objects as data transfer objects?You can do what you’re looking for with something like this:
Problem number 2: It might be fixed after you’ve resolved problem number 1. The problem might be that your action is expecting an
int
forBlogId
but you’re currently not passingBlogId
.If that doesn’t work, open the network tab in the browser and make sure it’s passing the POST body. Then check for
ModelState
errors in your action to see if any of the properties are failing validation.Since in your original post you were using contentType: "application/json", you just needed to add a [FromBody] attribute and everything would be working
in your second post the code is working because in this case your content type is form-data (by default). In this case you don’t neeed [FromBody] attribute