如何向以前创建的对象添加属性

时间:2011-01-04 18:06:03

标签: c# asp.net-mvc asp.net-mvc-2

我不确定我尝试做的事情是否合理。我试图在asp.net mvc中使用可移植的分页小部件。

棘手的部分是我正在存储路线值的对象。

public class PaginatedList<T> : List<T>
{
    public PaginationData PaginationData { get; private set; }

    public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize)
    {
        PaginationData = new PaginationData( source.Count() , pageIndex, pageSize);
        this.AddRange(source.Skip((PaginationData.PageIndex - 1) * PaginationData.PageSize).Take(PaginationData.PageSize));
    }

}

public class PaginationData
{
    ////////////////////////////////////////////
    public object PageRoute { get; set; } //   <-- object for route values
    ////////////////////////////////////////////
    public bool HasPreviousPage { get { return (PageIndex > 1); } }
    public bool HasNextPage { get { return (PageIndex < TotalPages); } }
    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public int TotalCount { get; private set; }
    public int TotalPages { get; private set; }

    public PaginationData(int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        PageSize = pageSize;
        TotalCount = count;
        TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
    }
}

所以我可以在控制器级别定义基本路由信息,如下所示:

        PaginatedList<Member> paginatedMembers = new PaginatedList<Member>(members, page, 2);
        // define base url route
        paginatedMembers.PaginationData.PageRoute = new { controller = "AdminMember", action = "MemberList", keyword = keyword };

这允许我为页面链接应该包含其他数据的情况添加keyword=keyword之类的值。

然后使用共享的部分视图显示分页:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Genesis_0_02.Utilities.PaginationData>" %>

<% if (Model.HasPreviousPage) { %> 
        <%: Html.ActionLink("Previous", ViewContext.RouteData.Values["action"].ToString(), new { page = (Model.PageIndex - 1) })%>

    <% } %> 
    <% for (int i = 1; i <= Model.TotalPages; i++) %>
    <% { %>
            <!--How do I add {page=i} to Model.PageRoute object below?-->
            <%: Html.RouteLink(i.ToString(), Model.PageRoute)%>

    <% } %>

    <% if (Model.HasNextPage) {  %> 
        <%: Html.ActionLink("Next", ViewContext.RouteData.Values["action"].ToString(), new { page = (Model.PageIndex + 1) })%>
    <% } %> 

如您所见......上述部分视图尚未完成。我特意在这条线上工作:

            <!--How do I add {page=i} to Model.PageRoute object below?-->
            <%: Html.RouteLink(i.ToString(), Model.PageRoute)%>

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:2)

您可以将PaginationData类修改为以下内容。注意:为了与MVC框架保持一致,我将PageRoute属性重命名为RouteValues

public class PaginationData
{
    private System.Web.Routing.RouteValueDictionary _RouteValues;

    public System.Web.Routing.RouteValueDictionary RouteValues
    {
        get
        {
            if (_RouteValues == null)
            {
                _RouteValues = new System.Web.Routing.RouteValueDictionary();
            }
            return _RouteValues;
        }
        private set { _RouteValues = value; }
    }

    public void SetRouteValues(object routeValues)
    {
        this.RouteValues = new System.Web.Routing.RouteValueDictionary(routeValues);
    }

    public bool HasPreviousPage { get { return (PageIndex > 1); } }
    public bool HasNextPage { get { return (PageIndex < TotalPages); } }
    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public int TotalCount { get; private set; }
    public int TotalPages { get; private set; }

    public PaginationData(int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        PageSize = pageSize;
        TotalCount = count;
        TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
    }
}

然后,您可以通过执行以下操作添加到路线值:

Model.RouteValues.Add("key", value);

Model.RouteValues["key"] = value;

使用扩展方法合并RouteValueDictionaries的替代方法

以下是一些为RouteValueDictionaries提供某些功能的扩展方法。

public static class RouteValueExtensions
{
    public static void Merge(this RouteValueDictionary routeValuesA, object routeValuesB)
    {
        foreach (var entry in new RouteValueDictionary(routeValuesB))
        {
            routeValuesA[entry.Key] = entry.Value;
        }
    }

    public static RouteValueDictionary With(this RouteValueDictionary routeValuesA, object routeValuesB)
    {
        routeValuesA.Merge(routeValuesB);
        return routeValuesA;
    }

    public static RouteValueDictionary With(this RouteValueDictionary routeValues, params object[] routeValuesToMerge)
    {
        if (routeValues != null)
        {
            for (int i = 0; i < routeValuesToMerge.Length; i++)
            {
                routeValues.Merge(routeValuesToMerge[i]);
            }
        }
        return routeValues;
    }

    public static RouteValueDictionary RouteValues(this HtmlHelper htmlHelper, object routeValues)
    {
        return new RouteValueDictionary(routeValues);
    }

    public static RouteValueDictionary RouteValues(this HtmlHelper htmlHelper, object routeValuesA, object routeValuesB)
    {
        return htmlHelper.RouteValues(routeValuesA).With(routeValuesB);
    }

    public static RouteValueDictionary RouteValues(this HtmlHelper htmlHelper, params object[] routeValues)
    {
        if (routeValues != null && routeValues.Length > 0)
        {
            var result = htmlHelper.RouteValues(routeValues[0]);
            for (int i = 1; i < routeValues.Length; i++)
            {
                result.Merge(routeValues[i]);
            }
            return result;
        }
        else
        {
            return new RouteValueDictionary();
        }
    }
}

在这种情况下,我认为您可以将它们与原始模型实现一起使用,如下所示:

Html.RouteLink(i.ToString(), Html.RouteValues(Model.PageRoute, new { page = i }))

Html.RouteLink(i.ToString(), Html.RouteValues(Model.PageRoute).With(new { page = i }))

缺点是使用这种方法会有一些过度的反射和实例化新的RouteValueDictionary对象。