【问题标题】:.NET CORE Invoke ViewComponent from Controller.NET CORE 从控制器调用 ViewComponent
【发布时间】:2022-01-14 18:35:15
【问题描述】:

我在从控制器加载 ViewComponent 时遇到问题,我的主视图是 Contact.cshtml,而我的 ViewComponent 是 AddContact.cshtml。 AddContact 是一个带有提交按钮的简单表单,我正在尝试获取它,以便当模型无效时,组件会刷新输入的数据和模型验证消息。

问题是当我在控制器中返回 "ViewComponent("AddContact", newContact)" 时,模型“newContact”无效,它会在一个全新的页面中重新加载 ViewComponent,而不是作为联系人视图中的一部分。是否有一些我遗漏的语法或者这完全需要其他东西?

联系方式.cshtml:

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

AddContact.cshtml

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

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

控制器:

[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");
 }

组件:

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

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core model-validation asp.net-core-viewcomponent


    【解决方案1】:

    您可以创建一个特定的操作来将请求定向到 ViewCompoent。

    这是一个例子,

    对于您将被定向的cshtml

    &lt;a href="#" data-url='@Url.Action("LoadParametersContent","Home",new {key="Home"})'&gt;

    为了你的HomeContoller.cs

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

    对于HomeViewComponent.cs

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

    之后,您应该在 Shared>Components>Home 下将组件创建为 Home.cshtml

    奖金:

    我有一个左侧导航栏。使用该导航栏中的锚点,我正在使用视图组件更改右侧的内容。这是实现这一点的 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);
        });
    });

    【讨论】:

      【解决方案2】:

      问题是当我返回 "ViewComponent("AddContact", newContact)" 在具有无效模型“newContact”的控制器中,它重新加载 ViewComponent 在一个全新的页面中,而不是作为部分 联系人视图。

      原因是程序先执行了if语句的内容,然后代码返回到AddContact页面。所以它重新加载了 ViewComponent 在一个全新的页面中,而不是作为部分 联系人视图。

      您可以尝试将 return ViewComponent("AddContact", newContact); 更改为 return View("Contact"); 在您的 if 控制器中的方法。

      我做了一个演示来满足您的要求。 Demo如下。

      1.在控制器中,使用Contact动作。

      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.在Contact.cshtml中,添加@await Component.InvokeAsync("AddContact")

      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

      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.Component 类是你的 AddContact。

      结果:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-05
        • 2020-05-04
        • 2018-04-09
        • 2020-04-14
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 2021-05-01
        相关资源
        最近更新 更多