ASP.NET Core 6 MVC视图组件隐藏输入无法传递至控制器Post方法
视图组件中Post请求无法传递隐藏字段参数到控制器
问题:在视图组件的表单中通过隐藏输入向Post动作方法传递参数时,控制器接收的值为null或0,但相同逻辑在普通视图中可以正常工作。
视图组件类(用于在Edit视图中展示图片)
public class EditPostImageComponent: ViewComponent { private IPostService _postService; public EditPostImageComponent(IPostService postService) { _postService = postService; } public async Task<IViewComponentResult> InvokeAsync(ShowPostListItemViewModel showPostListItemViewModel) { return await Task.FromResult((IViewComponentResult)View("EditPostImage", _postService.GetPostGallary(showPostListItemViewModel.PostId))); } }
视图组件视图(用于展示图片)
@model List<DataLayer.Models.ViewModels.Post.ShowPostListItemViewModel> @foreach (var item in Model) { <div class="col-lg-4 mb-4"> @if (item.ImageName != null) { <form method="post" asp-area="Admin" asp-controller="Post" asp-action="DeletePostImg"> <input type="hidden" asp-for="@item.PostId" /> <input type="hidden" asp-for="@item.Title" /> <input type="hidden" asp-for="@item.Description" /> <input type="hidden" asp-for="@item.ImageName" /> <div class="blog-item position-relative overflow-hidden rounded mb-2"> <img id="imgPost" class="img-fluid thumbnail" src="/img/post/@item.Title/@item.ImageName" alt=""> <br /> <br /> @*<a asp-controller="Post" asp-action="DeletePostImg" asp-route-id="@item.PostId" class="btn btn-danger btn-sm">Delete</a>*@ <input type="submit" class="btn btn-danger btn-sm" value="Delete" /> </div> </form> } else { <div class="blog-item position-relative overflow-hidden rounded mb-2"> <img id="imgAvatar" class="thumbnail" src="/UserAvatar/Defult.jpg" /> </div> } </div>
控制器Post动作方法(用于直接删除数据库中的图片)
[HttpPost] public void DeletePostImg(ShowPostListItemViewModel showPostListItemViewModel) { _postService.DeletePostImage(showPostListItemViewModel); }
问题原因
视图组件的模型是List<ShowPostListItemViewModel>,循环中使用asp-for="@item.PostId"时,会生成带索引的name属性(如[0].PostId),但控制器接收的是单个ShowPostListItemViewModel对象,模型绑定无法匹配这种带索引的参数名,导致无法正确赋值。而普通视图若模型为单个实体,asp-for生成的是直接的属性名(如PostId),因此能正常绑定。
解决方案
方案1:手动指定隐藏字段的name属性
放弃asp-for,直接设置name属性为控制器模型对应的属性名,确保参数名匹配:
<input type="hidden" name="PostId" value="@item.PostId" /> <input type="hidden" name="Title" value="@item.Title" /> <input type="hidden" name="Description" value="@item.Description" /> <input type="hidden" name="ImageName" value="@item.ImageName" />
方案2:通过路由传递核心参数
如果仅需关键参数,可将其放在路由中,简化参数传递:
<form method="post" asp-area="Admin" asp-controller="Post" asp-action="DeletePostImg" asp-route-postId="@item.PostId" asp-route-imageName="@item.ImageName"> <input type="hidden" name="Title" value="@item.Title" /> <input type="hidden" name="Description" value="@item.Description" /> <!-- 其他内容不变 --> </form>
对应的控制器方法:
[HttpPost] public void DeletePostImg(int postId, string imageName, string title, string description) { var model = new ShowPostListItemViewModel { PostId = postId, ImageName = imageName, Title = title, Description = description }; _postService.DeletePostImage(model); }
内容的提问来源于stack exchange,提问作者n.e
相关产品推荐
相关产品推荐

