ASP.NET Core中的HTML.Partial不触发控制器方法 [英] HTML.Partial not firing controller method in ASP.NET Core

查看:171
本文介绍了ASP.NET Core中的HTML.Partial不触发控制器方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我的 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.

  1. 在应用程序根路径中添加TagHelpers文件夹,然后添加HtmlHelperViewExtensions.cs文件:

  1. 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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆