Reputation: 649
I am making my first asp.net mvc project forum system. I am trying to add post but i don't know how to send data from view to controller. I have viewmodels that i am using, but i want to send current threadId to post action and to write it in database. Here is my code:
public ActionResult Create(CreatePostInputModel input)
{
if (ModelState.IsValid)
{
var content = sanitizer.Sanitize(input.Content);
var post = new Post
{
ThreadId = ViewBag.ThreadId,
AuthorId = this.User.Identity.GetUserId(),
Content = content,
IsDeleted = false,
CreatedOn = DateTime.Now,
PreserveCreatedOn = true
};
this.Data.SaveChanges();
this.RedirectToRoute("Show thread", new {id = post.ThreadId, name = post.Thread.Title });
}
public class PostViewModel : IMapFrom<Data.Models.Post>, IHaveCustomMappings
{
public PostViewModel()
{
this.CreatePostInputModel = new CreatePostInputModel();
}
public int ThreadId { get; set; }
public string Title { get; set; }
public IEnumerable<Data.Models.Post> Posts { get; set; }
public CreatePostInputModel CreatePostInputModel { get; set; }
public void CreateMappings(IConfiguration configuration)
{
configuration.CreateMap<Data.Models.Post, PostViewModel>()
.ForMember(m => m.Title, opt => opt.MapFrom(t => t.Thread.Title))
.ForMember(m => m.ThreadId, opt => opt.MapFrom(t => t.ThreadId));
configuration.CreateMap<Thread, PostViewModel>()
.ForMember(m => m.Posts, opt => opt.MapFrom(t => t.Posts))
.ReverseMap();
}
}
my views
@model IEnumerable<ForumSystem.Web.ViewModels.Post.PostViewModel>
@{
ViewBag.Title = "Display";
}
<div class="container">
@foreach (var thread in Model)
{
ViewBag.ThreadId = thread.ThreadId;
<div class="row">
<h4>@thread.Title</h4>
@foreach (var post in thread.Posts)
{
<div class="col-md-10">
<div class="row">
<div>@post.Content</div>
<span>
</span>
</div>
</div>
}
</div>
<div>
@{ Html.RenderPartial("_CreatePartial", thread.CreatePostInputModel); }
</div>
}
</div>
Partial view:
@model ForumSystem.Web.InputModels.Post.CreatePostInputModel
@using (Html.BeginForm("Create", "Post", FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
@Html.EditorFor(model => model.Content)
</div>
<div class="form-group text-center">
<input type="submit" value="Добави пост" class="btn btn-primary btn-lg" />
</div>
}
In CreatePostInputModel I have only one string property Content. I have tried using viewbag, sending parameter from partial view form, but from there i can't get ThreadId. What's the right way to do it? I am thinking of making CreatePostInputModel constructor that takes threadId, but I'am not sure if this is the right way.
Upvotes: 1
Views: 239
Reputation: 12334
You can use a hidden
input field to embed the current thread id. You will need to do that inside your form in the partial view.
Your main view:
@model IEnumerable<ForumSystem.Web.ViewModels.Post.PostViewModel>
@{
ViewBag.Title = "Display";
}
<div class="container">
@foreach (var thread in Model)
{
ViewBag.ThreadId = thread.ThreadId;
<div class="row">
<h4>@thread.Title</h4>
@foreach (var post in thread.Posts)
{
<div class="col-md-10">
<div class="row">
<div>@post.Content</div>
<span>
</span>
</div>
</div>
}
</div>
<div>
@{ Html.RenderPartial("_CreatePartial", thread); }
</div>
}
</div>
Your partial view:
@modelForumSystem.Web.ViewModels.Post.PostViewModel
@using (Html.BeginForm("Create", "Post", FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary("", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ThreadId)
<div class="form-group">
@Html.EditorFor(model => model.CreatePostInputModel.Content)
</div>
<div class="form-group text-center">
<input type="submit" value="Добави пост" class="btn btn-primary btn-lg" />
</div>
}
And in your controller just fetch this id (don't forget to check if the thread with such threadId exists in the DB):
public ActionResult Create(int threadId, CreatePostInputModel input)
{
if (ModelState.IsValid)
{
var content = sanitizer.Sanitize(input.Content);
var post = new Post
{
ThreadId = threadId,
AuthorId = this.User.Identity.GetUserId(),
Content = content,
IsDeleted = false,
CreatedOn = DateTime.Now,
PreserveCreatedOn = true
};
this.Data.SaveChanges();
this.RedirectToRoute("Show thread", new {id = post.ThreadId, name = post.Thread.Title });
}
Upvotes: 1