简体   繁体   English

.NET CORE 从 Controller 调用 ViewComponent

[英].NET CORE Invoke ViewComponent from Controller

I am having issues with loading a ViewComponent from a controller, my main view is Contact.cshtml and my ViewComponent is AddContact.cshtml.我在从 controller 加载 ViewComponent 时遇到问题,我的主视图是 Contact.cshtml,而我的 ViewComponent 是 AddContact.cshtml。 AddContact is a simple form with a submit button, I am trying to get it so that when the model is invalid, the component refreshes with the data that was entered and the model validation messages. AddContact 是一个带有提交按钮的简单表单,我正在尝试获取它,以便当 model 无效时,组件会使用输入的数据和 model 验证消息进行刷新。

The problem is when I return "ViewComponent("AddContact", newContact)" in the controller with then invalid model 'newContact', it reloads the ViewComponent in an entirely new page and not as a partial in the Contact view.问题是当我在 controller 中返回“ViewComponent("AddContact", newContact)" 时,model 'newContact' 无效时,它会在一个全新的页面中重新加载 ViewComponent,而不是在联系人视图中作为部分。 Is there some syntax I am missing or would this require something else entirely?是否有一些我遗漏的语法或者这完全需要其他东西?

Contact.cshtml:联系人.cshtml:

@await Component.InvokeAsync("AddContact", new { addContact = newContactModel })

AddContact.cshtml AddContact.cshtml

@using (Html.BeginForm("AddContact", "Contact", FormMethod.Post))
{
    ....

    <input id="addContactBtn" type="submit" value="Add" class="btn btn-success">
}

Controller: Controller:

[HttpGet]
public ActionResult AddContact()
{
      return ViewComponent("AddContact");
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddContact(AddContact_VM newContact)
{
      if (!ModelState.IsValid)
      {
            return ViewComponent("AddContact", newContact);
      }

      OperationStatus opStat = granteeRepo.AddContact(newContact);

      return View("Contact");
 }

Component:零件:

public class AddContact : ViewComponent
{
    public IViewComponentResult Invoke(AddContact_VM newContact)
    {
         return View("AddContact", newContact);
    }
}

You can create a spesific action to direct requests to ViewCompoent.您可以创建一个特定的操作来将请求定向到 ViewCompoent。

Here is an example,这是一个例子,

For your cshtml that will be directed:对于将被定向的cshtml

 <a href="#" data-url='@Url.Action("LoadParametersContent","Home",new {key="Home"})'>

For your HomeContoller.cs对于您的HomeContoller.cs

   public IActionResult LoadParametersContent(string key)
   {
       return ViewComponent(key);
   }

For HomeViewComponent.cs :对于HomeViewComponent.cs

    public class HomeViewComponent : ViewComponent
    {
        public IViewComponentResult Invoke()
        {
            return View("Home");
        }
    }

After that you should create your component as Home.cshtml under Shared>Components>Home.之后,您应该在 Shared>Components>Home 下将组件创建为Home.cshtml

Bonus:奖金:

I have a left-sided navbar.我有一个左侧导航栏。 With anchors in that navbar I'm changing the content on the right with viewcomponents.使用该导航栏中的锚点,我正在使用视图组件更改右侧的内容。 Here is the jquery that makes that happen:这是实现这一目标的 jquery:

 $('.nav-link').on('click', function (evt) { evt.preventDefault(); evt.stopPropagation(); var $detailDiv = $('#content-right'), url = $(this).data('url'); $.get(url, function (data) { $detailDiv.html(data); }); });

The problem is when I return "ViewComponent("AddContact", newContact)" in the controller with then invalid model 'newContact', it reloads the ViewComponent in an entirely new page and not as a partial in the Contact view.问题是当我在 controller 中返回“ViewComponent("AddContact", newContact)" 时,model 'newContact' 无效时,它会在一个全新的页面中重新加载 ViewComponent,而不是在联系人视图中作为部分。

The reason is the program first executes the content of the if statement, and then the code returns to the AddContact page.So it reloads the ViewComponent in an entirely new page and not as a partial in the Contact view.原因是程序首先执行 if 语句的内容,然后代码返回到 AddContact 页面。所以它在一个全新的页面中重新加载 ViewComponent,而不是在 Contact 视图中作为部分。

You can try to change the return ViewComponent("AddContact", newContact);您可以尝试更改返回 ViewComponent("AddContact", newContact); into return View("Contact");进入返回视图(“联系人”); in your if method in your controller.在您的 controller 中的if方法中。

I do a Demo to meet your requirement.我做了一个演示来满足您的要求。 The Demo as below. Demo如下。

1.In controller, use Contact action. 1.在 controller 中,使用接触动作。

public class ctController : Controller
    {
        [HttpGet]
        public IActionResult Contact()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Contact(AddContact_VM newContact)
        {

            if (!ModelState.IsValid)
            {
                return View("Contact");
            }

            OperationStatus opStat = granteeRepo.AddContact(newContact);
            return View("Contact");
        }

2.In Contact.cshtml, add @await Component.InvokeAsync("AddContact") 2.在Contact.cshtml中,添加@await Component.InvokeAsync("AddContact")

3.In AddContact.cshtml, change action name in form. 3.在 AddContact.cshtml 中,更改表单中的操作名称。

   @model MVCviewcompent.Models.AddContact_VM
    @using (Html.BeginForm("Contact", "ct", FormMethod.Post))
    {
        <form asp-controller="ct" asp-action="Contact" method="post">
            <table border="0" cellpadding="2" cellspacing="2">
                <tr>
                    <td>Username</td>
                    <td>
                        <input asp-for="Username" />
                    </td>
                    <td>
                        <span asp-validation-for="Username"></span>
                    </td>
                </tr>
                <tr>
                    <td>Password</td>
                    <td>
                        <input asp-for="Password" type="password" />
                    </td>
                    <td>
                        <span asp-validation-for="Password"></span>
                    </td>
                </tr>
                <tr>
                    <td>Age</td>
                    <td>
                        <input asp-for="Age" />
                    </td>
                    <td>
                        <span asp-validation-for="Age"></span>
                    </td>
                    
                </tr>
    
                <tr>
                    <td>&nbsp;</td>
                    <td>
                        <input type="submit" value="Save" />
                    </td>
                </tr>
            </table>
        </form>
}

4.In AddContact_VM.cs 4.在 AddContact_VM.cs

public class AddContact_VM
    {
        [Required]
        [MinLength(3)]
        [MaxLength(10)]
        public string Username
        {
            get;
            set;
        }

        [Required]
        [MinLength(3)]
       
        public string Password
        {
            get;
            set;
        }


        [Required]
        [Range(18, 50)]
        public int Age
        {
            get;
            set;
        }
   }

5.The Component class is your AddContact. 5.组件 class 是您的 AddContact。

Results:结果:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM