ASP.NET Core中的HTML.Partial不触发控制器方法 [英] HTML.Partial not firing controller method in ASP.NET Core
问题描述
为什么我的 html.partial
无法在控制器中触发 Create
方法?
Why is my html.partial
not firing the Create
method in controller?
这是我的chtml代码:
Here is my chtml code:
<div class="modal fade" id="UnitModal">
<div class="modal-dialog">
<div class="modal-content">
@Html.Partial("Create")
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
这是我在控制器中的代码:
Here is my code in controller:
// GET: Units/Create
public IActionResult Create()
{
return View();
}
// POST: Units/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(UnitViewModel unit)
{
if (ModelState.IsValid)
{
var model = _mapper.Map<Unit>(unit);
_context.Add(model);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(unit);
}
每次我单击按钮以显示创建模式时,从控制器获取 Create
均不会触发.但是Post Create
正在触发,并正确保存了数据.我想念什么?
Every time I click the button to display the create modal, Get Create
from controller is not firing. But Post Create
is firing, and properly saving the data. What am I missing?
样本输出:
推荐答案
Html.Partial
将仅呈现特殊视图,而不会调用action方法(Get方法).
The Html.Partial
will only render the special view, it will not calling the action method (Get method).
要执行控制器操作并在Asp.net Core中呈现部分视图,如David所说,您可以使用
To execute the controller action and render the partial view in Asp.net Core, as David said, you could use the View Components. Besides, you could also refer the following steps to use @Html.RenderAction()
method in asp.net Core MVC application.
-
在应用程序根路径中添加TagHelpers文件夹,然后添加HtmlHelperViewExtensions.cs文件:
Add a TagHelpers folder in application root path, then, add the HtmlHelperViewExtensions.cs file:
public static class HtmlHelperViewExtensions
{
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, object parameters = null)
{
var controller = (string)helper.ViewContext.RouteData.Values["controller"];
return RenderAction(helper, action, controller, parameters);
}
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, object parameters = null)
{
var area = (string)helper.ViewContext.RouteData.Values["area"];
return RenderAction(helper, action, controller, area, parameters);
}
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
{
if (action == null)
throw new ArgumentNullException(nameof(controller));
if (controller == null)
throw new ArgumentNullException(nameof(action));
var task = RenderActionAsync(helper, action, controller, area, parameters);
return task.Result;
}
private static async Task<IHtmlContent> RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
{
// fetching required services for invocation
var currentHttpContext = helper.ViewContext.HttpContext;
var httpContextFactory = GetServiceOrFail<IHttpContextFactory>(currentHttpContext);
var actionInvokerFactory = GetServiceOrFail<IActionInvokerFactory>(currentHttpContext);
var actionSelector = GetServiceOrFail<IActionDescriptorCollectionProvider>(currentHttpContext);
// creating new action invocation context
var routeData = new RouteData();
var routeParams = new RouteValueDictionary(parameters ?? new { });
var routeValues = new RouteValueDictionary(new { area, controller, action });
var newHttpContext = httpContextFactory.Create(currentHttpContext.Features);
newHttpContext.Response.Body = new MemoryStream();
foreach (var router in helper.ViewContext.RouteData.Routers)
routeData.PushState(router, null, null);
routeData.PushState(null, routeValues, null);
routeData.PushState(null, routeParams, null);
var actionDescriptor = actionSelector.ActionDescriptors.Items.First(i => i.RouteValues["Controller"] == controller && i.RouteValues["Action"] == action);
var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);
// invoke action and retreive the response body
var invoker = actionInvokerFactory.CreateInvoker(actionContext);
string content = null;
await invoker.InvokeAsync().ContinueWith(task =>
{
if (task.IsFaulted)
{
content = task.Exception.Message;
}
else if (task.IsCompleted)
{
newHttpContext.Response.Body.Position = 0;
using (var reader = new StreamReader(newHttpContext.Response.Body))
content = reader.ReadToEnd();
}
});
return new HtmlString(content);
}
private static TService GetServiceOrFail<TService>(HttpContext httpContext)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
var service = httpContext.RequestServices.GetService(typeof(TService));
if (service == null)
throw new InvalidOperationException($"Could not locate service: {nameof(TService)}");
return (TService)service;
}
}
在_ViewImports.cshtml
Add the folder reference in the _ViewImports.cshtml
@using WebApplication2.TagHelpers
使用 @ Html.RenderAction(< action name>")
将部分视图加载到主视图中.
Using @Html.RenderAction("<action name>")
to load the partial view in the Main View.
[注意]通过使用以上方法,在加载主视图时调用了操作方法(局部视图),而不是单击添加单元".按钮.
[Note] By using above method, the action method (partial view) was called when loading the main view, instead of click the "Add Unit" button.
如果要在单击添加"按钮时加载部分视图,则最好使用JQuery来加载部分视图.示例代码如下:
If you want to load the partial view when click the Add button, you'd better to use JQuery to load the partial view. Sample code as below:
<button type="button" id="btn_addunit" class="btn btn-primary" data-toggle="modal" data-target="#UnitModal">
Add Unit
</button>
<div class="modal fade" id="UnitModal">
<div class="modal-dialog">
<div class="modal-content" id="modal_content">
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
@section Scripts{
<script type="text/javascript">
$(document).ready(function () {
$("#btn_addunit").click(function () {
$("#modal_content").load("/Home/Create"); //change the controller action to yours.
});
});
</script>
}
这篇关于ASP.NET Core中的HTML.Partial不触发控制器方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!