在 ASP.NET MVC 中单击按钮时呈现部分视图

Posted

技术标签:

【中文标题】在 ASP.NET MVC 中单击按钮时呈现部分视图【英文标题】:Rendering partial view on button click in ASP.NET MVC 【发布时间】:2015-05-22 10:32:40 【问题描述】:

我将要描述的问题与我已经发现的问题非常相似(例如this post with nearly identical name),但我希望我可以将其变成不重复的问题。

我在 Visual Studio 中创建了一个新的 ASP.NET MVC 5 应用程序。然后,我定义了两个模型类:

public class SearchCriterionModel

  public string Keyword  get; set; 


public class SearchResultModel

  public int Id  get; set; 
  public string FirstName  get; set; 
  public string Surname  get; set; 

然后我创建了SearchController,如下所示:

public class SearchController : Controller

  public ActionResult Index()
  
    return View();
  

  public ActionResult DisplaySearchResults()
  
    var model = new List<SearchResultModel>
    
      new SearchResultModel  Id=1, FirstName="Peter", Surname="Pan" ,
      new SearchResultModel  Id=2, FirstName="Jane", Surname="Doe" 
    ;
    return PartialView("SearchResults", model);
  

以及视图Index.cshtml(强烈键入SearchCriterionModel作为模型和模板编辑)和SearchResults.cshtml作为@类型模型的部分视图987654328@(模板列表)。

这是索引视图:

@model WebApplication1.Models.SearchCriterionModel

@
  ViewBag.Title = "Index";


@using (Html.BeginForm())

  @Html.AntiForgeryToken()

  <div class="form-horizontal">
    <h4>SearchCriterionModel</h4>
    <hr />
    @Html.ValidationSummary(true, "", new  @class = "text-danger" )
    <div class="form-group">
      @Html.LabelFor(model => model.Keyword, htmlAttributes: new  @class = "control-label col-md-2" )
      <div class="col-md-10">
        @Html.EditorFor(model => model.Keyword, new  htmlAttributes = new  @class = "form-control"  )
        @Html.ValidationMessageFor(model => model.Keyword, "", new  @class = "text-danger" )
      </div>
    </div>

    <div class="form-group">
      <div class="col-md-offset-2 col-md-10">
        <input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='@Url.Action("DisplaySearchResults", "SearchController")'" />
      </div>
    </div>
  </div>


<div>
  @Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">

</div>

如您所见,我在标准模板下方添加了divid="searchResults",并编辑了按钮。我想要的是在底部的div 中显示部分视图SearchResults.cshtml,但只有在单击按钮之后。我已经通过使用@Html.Partial("SearchResults", ViewBag.MyData) 成功地在那里显示了部分视图,但是它是在第一次加载父视图时呈现的,并且我已经在Index() 方法中设置了ViewBag.MyData,这不是我想要的。

总结:点击按钮后,我将获得一些ListSearchResultModel 实例(通过数据库访问),然后应该渲染部分视图,使用这个新获得的数据作为模型。 我怎样才能做到这一点?我似乎已经在第一步失败了,即使用上面的代码对按钮单击做出反应。现在,我导航到 URL ~/Search/DisplaySearchResults,当然那里什么都没有,也没有调用任何代码隐藏方法。 在传统的 ASP.NET 中,我只需添加一个服务器端 OnClick 处理程序,为网格设置 DataSource 并显示网格。但是在 MVC 中,我已经在这个简单的任务上失败了......

更新: 把按钮改成@Html.ActionLink 终于可以进入控制器方法了。但自然因为它返回的是部分视图,所以它显示为整个页面内容。所以问题是:如何告诉要在客户端的特定div 内呈现部分视图?

【问题讨论】:

通常,您处理按钮单击事件并使用 ajax 将搜索文本传递给返回部分视图的控制器方法,然后使用返回的结果更新 DOM。查看 jquery ajax()load() 方法。 我会用你需要的整个 HTML 为你的 DisplaySearchResults 操作创建新视图,并在索引视图中删除这个 serchResult div。它应该可以工作,但之后我会创建一些部分并重构这两个视图(索引和 DisplaySearchResults),因为代码重复 【参考方案1】:

将按钮改为

<button id="search">Search</button>

并添加以下脚本

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() 
  var keyWord = $('#Keyword').val();
  $('#searchResults').load(url,  searchText: keyWord );
)

并修改控制器方法以接受搜索文本

public ActionResult DisplaySearchResults(string searchText)

  var model = // build list based on parameter searchText
   return PartialView("SearchResults", model);

jQuery .load 方法调用您的控制器方法,传递搜索文本的值并使用部分视图更新 &lt;div&gt; 的内容。

旁注:这里可能不需要使用&lt;form&gt; 标签和@Html.ValidationSummary()@Html.ValidationMessageFor()。你永远不会返回 Index 视图所以 ValidationSummary 没有意义,我假设你想要一个 null 搜索文本来返回所有结果,并且无论如何你没有属性 Keyword 的任何验证属性所以有无需验证。

编辑

基于 OP 的 cmets,SearchCriterionModel 将包含多个具有验证属性的属性,那么方法是包含一个提交按钮并处理表单 .submit() 事件

<input type="submit" value="Search" />

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() 
  if (!$(this).valid())  
    return false; // prevent the ajax call if validation errors
  
  var form = $(this).serialize();
  $('#searchResults').load(url, form);
  return false; // prevent the default submit action
)

控制器方法是

public ActionResult DisplaySearchResults(SearchCriterionModel criteria)

  var model = // build list based on the properties of criteria
  return PartialView("SearchResults", model);

【讨论】:

嗨,斯蒂芬,感谢您的回答。标签和其他东西就在那里,因为我希望我的方法很容易被复制,因此使用了一个内置的视图模板,它插入了这些东西。此外,在我的“真实”应用程序中,我将拥有比Keyword 更多的属性(应该提到这一点,抱歉!)。基本上,作为主视图模型的整个SearchCriterionModel搜索条件的集合。所以在代码隐藏中我想我可以使用当前的“绑定”对象来创建我的查询,然后用结果填充div 是的,你应该提到过 :) 但方法是相似的,除了你会使用$('#searchResults').load(url, $('form'.Serialize()); 序列化整个SearchCriterionModel,然后将方法更改为public ActionResult DisplaySearchResults(SearchCriterionModel model) 并返回一个部分基于模型值。在任何情况下都不需要@Html.ValidationSummary() 附带问题(我会在一分钟内尝试你的方法):我不能只使用无参数的load 并且当调用代码隐藏方法时,我得到的当前模型值已在视图中输入以构造查询,而不是将它们作为参数传递? 不确定我理解你的意思。如果您不将 Keyword 值(以及您在视图中呈现的模型中的任何其他值)传递给控制器​​,DisplaySearchResults 方法如何知道要返回什么? 另外,您可以使用&lt;input type="submit"&gt;,然后处理$('form').submit() 事件以在调用.load() 之前触发属性的客户端验证,但脚本需要包含return false; 以防止正常提交。【参考方案2】:

这是控制器代码。

public IActionResult AddURLTest()

    return ViewComponent("AddURL");

您可以使用 JQuery 加载方法来加载它。

$(document).ready (function()
    $("#LoadSignIn").click(function()
        $('#UserControl').load("/Home/AddURLTest");
    );
);

来源code link

【讨论】:

以上是关于在 ASP.NET MVC 中单击按钮时呈现部分视图的主要内容,如果未能解决你的问题,请参考以下文章

使用asp.net mvc在按钮单击成功时查看包消息无法正常工作?

在 ASP.net MVC 5 应用程序中单击按钮时使用 JavaScript/jQuery 将用户重定向到页面

ASP.NET Core 2,使用没有 MVC 的 Razor 页面单击按钮

Asp.net mvc 问题将部分页面加载到引导模式中

jQuery Validate:在 ASP.NET MVC 5 应用程序中添加事件以提交按钮单击

如何使用 jquery 或 ajax 在 c#/asp.net 中为 MVC 项目更新 razor 部分视图