Asp.net Mvc3 webgrid和分页

如何解决Asp.net Mvc3 webgrid和分页

我正在尝试学习Asp.net MVC。我知道它与形式不同,我可能需要改变思维方式。我的问题是关于webgrid的。当我将webgrid添加到我的页面并单击Post时单击搜索按钮时,它将使用传呼机等渲染表格。但是传呼机上的链接不是发布表单,它们只是链接,我丢失了所有表单数据。 控制器有两种索引方法,一种用于获取,另一种用于发布。为了让我什么都不做,在这种情况下,我只是创建新的viewmodel Search类并将其设置为view。对于我的发布方法,我抓住我的视图模型进行搜索并将填充的视图模型设置为视图。 问题:webgrid将分页器呈现为链接,因此它将进入索引以获取,但由于它不是发布请求,因此我没有填写任何表单字段,并且我的搜索将不会提供完全相同的结果集。 也许示例代码可以更好地解释它。 视图:
<form action=\"\" method=\"post\">

Esas no : @Html.TextBoxFor(x=>x.Name)
Yil : @Html.TextBoxFor(x=>x.Year)

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

<hr />
@ViewBag.Message
<hr />

@{ var grid = new WebGrid(Model.Results,rowsPerPage:5);}

@grid.GetHtml(tableStyle:\"table\",htmlAttributes:new {id=\"tbl\"} )

</form>
这是我的控制器:搜索发生在Index Post方法中,并且只有我的viewmodel类。
    private ISearchContext _sc;

    public  MyController(ISearchContext sc)
    {
        _dc = dc;
    }

    //
    // GET: /Dava/

    public ActionResult Index()
    {
        var search = new Search();
        ViewBag.Message = \"\";
        return View(search);
    }

    [HttpPost]
    public ActionResult Index(Search search)
    {

        Search sres = _dc.SearchFromRepository(search);
        ViewBag.Message = String.Format(\"Count:{0} \",sres.Results.Count);
        return View(sres);
    }
搜索模型类如下:
public class Search
{
    public int Year { get; set; }
    public string Name { get; set; }


    public IList<Item> Results { get; set; }

    public Search()
    {
        Results = new List<Item>();
    }
}
    

解决方法

        解决此问题的一种方法是使用javascript并订阅任何寻呼机链接的click事件,然后获取所需页面的值,将其注入到表单上的隐藏字段中,然后将表单提交给服务器,以便其他两个值也被发送。 因此,首先在
Search
视图模型上添加
Page
可为空的整数属性,并将相应的隐藏字段添加到表单中,该表单将包含选定的页码:
@Html.HiddenFor(x => x.Page,new { id = \"page\" })
然后,您只需要在页面中插入一个小的javascript代码段即可订阅寻呼机链接的.click事件:
$(function () {
    $(\'tfoot a\').click(function () {
        // when the user clicks on any of the pager links
        // try to extract the page number from the link and
        // set the value of the hidden field
        var page = this.href.match(/page=([0-9])+/)[1];
        $(\'#page\').val(page);

        // submit the form so that the POST action is invoked
        // passing along the search criteria (Name and Year) along
        // with the page hidden field value to the Index action
        $(\'form\').submit();

        // cancel the default action of the link which is to simply redirect
        // to the Index action using a GET verb.
        return false;
    });
});
    ,        这是一种不使用JavaScript的解决方法。 我所看到的问题是,分页链接没有收到任何必须保留的路由信息​​,例如搜索过滤器。海事组织这是一个公然的监督!稍微多考虑一下,就可以省去很多头痛! 该技术“丢弃”了WebGrid的内置分页,并使用Helper来生成分页链接以及所需的宝贵路由数据。 完成后,只需将WebGrid仅呈现为网格,然后使用Helper进行分页链接。这里的一个优势是您可以将那些放在顶部和底部,我们喜欢这样做。 我试图使用与NuGet放入您的解决方案的Pager.css中提供的CSS类似的CSS。对于某些人来说,该帮助程序应该足够完整,但是很容易扩展。 新新新我刚刚用Ajax版本更新了助手。我在Razor助手中有点不适应,所以我不知道如何重构它以使用通用模板。有人吗?重要的额外细节是传递
AjaxOptions
并确保将
POST
用作动词,否则您可能无法获得正确的控制器方法。 帮手(App_Code / LocalHelpers.cshtml):
@helper DoPager(System.Web.Mvc.HtmlHelper hh,string pageActionName,WebGrid grid,int maxPageLinks,object rvd) {
<div class=\"pager\">
<div class=\"pageof\">Page <b>@(grid.PageIndex + 1)</b> of <b>@grid.PageCount</b></div>
@if (grid.PageCount > 1) {
<ul>
<li>
@{ RouteValueDictionary rvdp1 = new RouteValueDictionary(rvd);
   rvdp1.Add(\"Page\",1);
}
@hh.ActionLink(\"<<\",pageActionName,rvdp1)
</li>
@{ int start = Math.Max(0,grid.PageIndex - maxPageLinks / 2); }
@for (int ix = 0; ix + start < grid.PageCount; ix++) {
    int pageno = start + ix + 1;
    var css = hh.Raw(pageno - 1 == grid.PageIndex ? \" class=\\\"highlighted\\\"\" : \"\");
    RouteValueDictionary rvdp = new RouteValueDictionary(rvd);
    rvdp.Add(\"Page\",pageno);
<li@css>
@hh.ActionLink(pageno.ToString(),rvdp)
</li>
    if (ix >= maxPageLinks) { break; }
}
<li>
@{ RouteValueDictionary rvdpX = new RouteValueDictionary(rvd);
   rvdpX.Add(\"Page\",grid.PageCount);
}
@hh.ActionLink(\">>\",rvdpX)
</li>
</ul>
}
</div>
}
@helper DoAjaxPager(System.Web.Mvc.AjaxHelper aa,System.Web.Mvc.Ajax.AjaxOptions aopts,System.Web.Mvc.HtmlHelper hh,1);
}
@aa.ActionLink(\"<<\",rvdp1,aopts)
</li>
@{ int start = Math.Max(0,pageno);
<li@css>
@aa.ActionLink(pageno.ToString(),rvdp,aopts)
</li>
    if (ix >= maxPageLinks) { break; }
}
<li>
@{ RouteValueDictionary rvdpX = new RouteValueDictionary(rvd);
   rvdpX.Add(\"Page\",grid.PageCount);
}
@aa.ActionLink(\">>\",rvdpX,aopts)
</li>
</ul>
}
</div>
}
视图:
<center>
@LocalHelpers.DoPager(Html,\"Index\",grid,10,new { CurrentFilter = ViewBag.CurrentFilter })
</center>
@grid.Table(
    tableStyle: \"centerit\",columns: grid.Columns(
        grid.Column(format: @<span>@Html.ActionLink(\"Edit\",\"Edit\",new { id = item.ID }) | @Html.ActionLink(\"Details\",\"Details\",new { id = item.ID }) | @Html.ActionLink(\"Delete\",\"Delete\",new { id = item.ID })</span>),grid.Column(\"PartNumber\",\"Part Number\"),grid.Column(\"Description\",\"Description\"),grid.Column(\"Regex\",\"Regex\")
            )
        )
<center>
@LocalHelpers.DoPager(Html,new { CurrentFilter = ViewBag.CurrentFilter })
</center>
在我看来,我正在回收\“ CurrentFilter \”以了解要进行过滤的内容。这将连接到控制器动作(未显示)。     ,        好。我有一个使用AJAX和Partial Views的更优雅的解决方案,可以彻底解决此问题。 这是我的模型:
public class SearchResultModel
{
        public string SearchText{ get; set; }
        public List<YourObject> Results { get; set; }
        public int TotalResults { get; set; }
}
搜索视图的结构如下:
@model SearchResultModel
@using (Ajax.BeginForm(\"SearchAction\",\"SearchController\",new AjaxOptions{UpdateTargetId = \"data-grid\",HttpMethod=\"Post\"}))
{
        @Html.TextBoxFor(m => m.SearchText)
        <input class=\"myButton\" type=\"submit\" value=\"Search\" />
}
<br />
<div id=\"data-grid\">
       @Html.Partial(\"SearchResults\",new SearchResultModel())
</div>
SearchResults部分视图为:
@model SearchResultModel
@{
    if (Model.Results != null && Model.Results.Count > 0)
    {
            var grid = new WebGrid(canPage: true,rowsPerPage: 10,canSort: true,ajaxUpdateContainerId: \"grid\");
            grid.Bind(Model.Results,rowCount: Model.TotalResults,autoSortAndPage: false);
            grid.Pager(WebGridPagerModes.All);

            @grid.GetHtml(htmlAttributes: new { id = \"grid\" },columns: grid.Columns(
                grid.Column(\"YourColumn1\"),grid.Column(\"YourColumn2\"),grid.Column(\"YourColumn3\")
            ),tableStyle: \"datatable\",rowStyle: \"datatable-normal\",alternatingRowStyle: \"datatable-alt\"
            );
    }
    else
    {
    <span>No Results</span>
    }
}
最后,控制器是:
public class SearchController
{
        public ActionResult SearchAction(SearchResultModel model)
        {
            return RedirectToAction(\"SearchResults\",new { id = model.SearchText });
        }

        public ActionResult SearchResults(string id)
        {
            string searchText = id;
            int page = 1;
            if(Request[\"page\"] != null)
                int.TryParse(Request[\"page\"],out page);

            SearchResultModel model = new SearchResultModel();
            //Populate model according to search text and page number
            //........
            //........
            return PartialView(model);
        }
}
希望这可以帮助您节省一些时间和焦虑!     ,我的答案包括继续在Session上进行搜索,仅此而已。 该解决方案很好,因为您可以使其适应实际情况,并且不需要特定的类或JQuery。 魔术发生在索引ActionResult(或默认的ActionResult,将以默认行为呈现网格页面)内部。 代码示例:
    [HttpGet]
    public ActionResult Index()//My default action result that will render the grid at its default situation
    {
        SearchViewModel model = new SearchViewModel(); 

        if (Request.IsAjaxRequest()) //First trick is here,this verification will tell you that someone sorted or paged the grid.
        {
            if (Session[\"SearchViewModel\"] != null) //If session is not empty,you will get the last filtred values from it.
                model = (SearchViewModel)Session[\"SearchViewModel\"];
        }
        else // If it is not an AjaxRequest,you have to clear your Session,so new requests to Index with default behavior won\'t display filtred values.
        {
            Session[\"SearchViewModel\"] = null;
        }

        model.GridResult = ExecuteFilter(model); // OPITIONAL! This code dependes on how is your real world situation. Just remember that you need to return a default behavior grid if the request was not called by the WebGrid,or return filtred results if WebGrid requested.
        return View(model);
    }
因此,这将是您的默认ActionResult。它将验证该请求是否由WebGrid分页或排序事件调用,以确定是否返回过滤结果或正常行为结果。 下一步是搜索POST ActionResult:
    [HttpPost]
    public ActionResult Index(SearchViewModel pesquisa) // IMPORTANT!! It is necessary to be the SAME NAME of your GET ActionResult. The reason for that I know,but won\'t discuss here because it goes out of the question.
    {
        SearchViewModel model = new SearchViewModel();
        model.GridResult = ExecuteFilter(pesquisa); // Execute your filter
        Session[\"SearchViewModel\"] = model; //Save your filter parameters on Session.
        return View(\"Index\",model);
    }
而已。 Index.cshtml没有任何技巧。只是一个SearchForm到ActionResult索引,将我的SearchViewModel作为参数传递。 为什么此解决方案有效? 好吧,当您单击排序或页面时,WebGrid将执行类似于以下的JavaScript:
$(\'#yourGrid\').load(\'it pass the url used to display your current Page,and some paging or sorting parameters,but those are used by the WebGrid\')
由于它执行.load()方法,因此该请求将是GET,并将命中索引GET ActionResult。但这是一个AJAX调用,因此我们的魔术技巧将使用您保存在Session上的参数再次执行过滤器。 我提醒的唯一详细信息是有关默认网格行为的。 GET Index ActionResult必须永远返回有效的网格结果,无论它是否在Session上进行过滤。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-