jquery datatables столбцы на стороне сервера - PullRequest
1 голос
/ 27 декабря 2011

Я использую таблицы данных jquery с обработкой mvc3 на стороне сервера C # / asp.net. теперь все работает, но у меня есть новая задача:

Я хочу скрыть некоторые столбцы по соображениям безопасности для определенных пользователей. Как создать столбцы на стороне сервера C # и перейти к Dataatable в представлении?

Ответы [ 2 ]

2 голосов
/ 27 декабря 2011

Контроллер может выглядеть так:

public JsonResult NewsJSON(jQueryDataTableParamModel param)
    {
        var news = _newsRepository.GetNews();

        string col = param.sColumns.Split(',')[param.iSortCol_0];
        string orderby = col + " " + param.sSortDir_0;

        if (param.sSearch != null)
            news = news.Search(param.sSearch);

        var qry = new PaginatedList<News>(news.OrderBy(orderby), param.iDisplayStart, param.iDisplayLength);

        return Json(new
        {
            sEcho = param.sEcho,
            iTotalRecords = qry.TotalCount,
            iTotalDisplayRecords = qry.TotalCount,
            aaData = (
                from n in qry
                select new[]
                {
                    n.Headline, 
                    n.DateCreated.ToString() 
                }).ToArray()
        }, JsonRequestBehavior.AllowGet);
    }

jQueryDataTableParamModel.cs

public class jQueryDataTableParamModel
{
    /// <summary>
    /// Request sequence number sent by DataTable,
    /// same value must be returned in response
    /// </summary>       
    public string sEcho { get; set; }

    /// <summary>
    /// Text used for filtering
    /// </summary>
    public string sSearch { get; set; }

    /// <summary>
    /// Number of records that should be shown in table
    /// </summary>
    public int iDisplayLength { get; set; }

    /// <summary>
    /// First record that should be shown(used for paging)
    /// </summary>
    public int iDisplayStart { get; set; }

    /// <summary>
    /// Number of columns in table
    /// </summary>
    public int iColumns { get; set; }

    /// <summary>
    /// Number of columns that are used in sorting
    /// </summary>
    public int iSortingCols { get; set; }

    /// <summary>
    /// Comma separated list of column names
    /// </summary>
    public string sColumns { get; set; }

    /// <summary>
    /// Sort column
    /// </summary>
    public int iSortCol_0 { get; set; }

    /// <summary>
    /// Asc or Desc
    /// </summary>
    public string sSortDir_0 { get; set; }

}

А в виду:

<script type="text/javascript" charset="utf-8">

$(function () {

$('#news').dataTable({    
"bSort" : true,        
"bServerSide": true,    
"sAjaxSource": "/News/NewsJSON",    
"bProcessing": true,    
"sPaginationType": "full_numbers",    
"iDisplayLength": 25,    
"aLengthMenu": [[25, 50, 100, 150, 200], [25, 50, 100, 150, 200]],

"aaSorting": [[1,'asc']],    
"aoColumns": [    
{ "sName": "Headline" }    
,{ "sName": "DateCreated" }    
]    
});    
});    
</script>


<table id="news" class="default-table" cellpadding="0" cellspacing="0">
<thead>

        <tr>
            <th>
                Headline
            </th>
            <th style="width: 114px">
                Created
            </th>
        </tr>
    </thead>
</table>

или аналогичный :) не уверен, правильно ли я получил JS, но.

/ Lasse

UPDATE:

Немного грязно, но что-то вроде:

public class DataTableOptions
{
    public string ID { get; set; }
    public string Url { get; set; }
    public string Cols { get; set; }
    public bool Sort { get; set; }
    public string ViewUrlLinkname { get; set; }
    public string EditUrlLinkname { get; set; }
    public string DeleteLinkname { get; set; }
    public string DeleteTitle { get; set; }
    public string DeleteYes { get; set; }
    public string DeleteNo { get; set; }
    public string DeleteMessage { get; set; }
}

public static class DataTableHelpers
{
    private static string aLengthMenu = "[[25, 50, 100, 150, 200], [25, 50, 100, 150, 200]]";

    public static MvcHtmlString DataTable(this HtmlHelper helper, DataTableOptions options)
    {
        string[] arrcols = options.Cols.Split(',');
        int sortOffset = arrcols.Where(x => x == "Delete" || x == "View" || x == "Edit").Count();

        StringBuilder sb = new StringBuilder();

        sb.AppendLine("<script type=\"text/javascript\" charset=\"utf-8\">");
        sb.AppendLine("$(function () {");
        sb.AppendLine("$('#" + options.ID + "').dataTable({");
        sb.AppendLine("\"bSort\" : " + options.Sort.ToString().ToLower() + ",");
        sb.AppendLine("\"oLanguage\": { \"sUrl\": \"" + oLanguage + "\" },");
        sb.AppendLine("\"bServerSide\": true,");
        sb.AppendLine("\"sAjaxSource\": \"" + options.Url + "\",");
        sb.AppendLine("\"bProcessing\": true,");
        sb.AppendLine("\"sPaginationType\": \"full_numbers\",");
        sb.AppendLine("\"iDisplayLength\": 25,");
        sb.AppendLine("\"aLengthMenu\": " + aLengthMenu + ",");
        sb.AppendLine("\"aaSorting\": [[" + sortOffset.ToString() + ",'asc']],");
        sb.AppendLine("\"aoColumns\": [");


        for (int i = 0; i < arrcols.Length; i++)
        {
            if (i > 0)
                sb.Append(",");

            switch (arrcols[i])
            {
                case "Delete":
                    sb.AppendLine("{");
                    sb.AppendLine("\"sName\": \"" + arrcols[i] + "\",");
                    sb.AppendLine("\"bSearchable\": false,");
                    sb.AppendLine("\"bSortable\": false,");
                    sb.AppendLine("\"fnRender\": function (oObj) {");
                    sb.Append("return '");
                    sb.Append("<a class=\"deletelink\" href=\"' + oObj.aData["+ i.ToString() + "] + '\">" + options.DeleteLinkname + "</a> ");
                    sb.Append("';");
                    sb.AppendLine("}");
                    sb.AppendLine("}");

                    break;
                case "Edit":
                    sb.AppendLine("{");
                    sb.AppendLine("\"sName\": \"" + arrcols[i] + "\",");
                    sb.AppendLine("\"bSearchable\": false,");
                    sb.AppendLine("\"bSortable\": false,");
                    sb.AppendLine("\"fnRender\": function (oObj) {");
                    sb.Append("return '");
                    sb.Append("<a class=\"editlink\" href=\"' + oObj.aData["+ i.ToString() + "] +'\">" + options.EditUrlLinkname + "</a> ");
                    sb.Append("';");
                    sb.AppendLine("}");
                    sb.AppendLine("}");

                    break;
                case "View":
                    sb.AppendLine("{");
                    sb.AppendLine("\"sName\": \"" + arrcols[i] + "\",");
                    sb.AppendLine("\"bSearchable\": false,");
                    sb.AppendLine("\"bSortable\": false,");
                    sb.AppendLine("\"fnRender\": function (oObj) {");
                    sb.Append("return '");
                    sb.Append("<a class=\"viewlink\" href=\"' + oObj.aData["+ i.ToString() + "] + '\">" + options.ViewUrlLinkname + "</a> ");
                    sb.Append("';");
                    sb.AppendLine("}");
                    sb.AppendLine("}");

                    break;
                default:
                    sb.AppendLine("{ \"sName\": \"" + arrcols[i] + "\" }");
                    break;
            }

        }

        sb.AppendLine("]");
        sb.AppendLine("});");
        sb.AppendLine("});");
        sb.AppendLine("</script>");

        if (options.DeleteLinkname != null)
        {
            sb.Append(ConfirmHelpers.RenderConfirm(options.DeleteTitle, options.DeleteYes, options.DeleteNo, options.DeleteMessage));
        }

        return MvcHtmlString.Create(sb.ToString());
    }

и в контроллере также передать ссылки:

    return Json(new
    {
        sEcho = param.sEcho,
        iTotalRecords = qry.TotalCount,
        iTotalDisplayRecords = qry.TotalCount,
        aaData = (
            from n in qry
            select new[]
            {
                Url.Action("Detail", new { newsID = n.NewsID, headline = n.Headline.ToURLParameter() }),
                Url.Action("Edit", new { newsID = n.NewsID, headline = n.Headline.ToURLParameter() }),
                Url.Action("Delete", new { newsID = n.NewsID }),
                n.Headline, 
                n.DateCreated.ToString() 
            }).ToArray()
    }, JsonRequestBehavior.AllowGet);
* * Тысяча двадцать-одина затем
    @Html.DataTable(Model.DataTableOptions)

    <table id="news" class="default-table" cellpadding="0" cellspacing="0">
<thead>
        <tr>
            <th style="width: 20px">
            </th>
            <th style="width: 50px">
            </th>
            <th style="width: 40px"></th>
            <th>
                Headline
            </th>....

Для удаления я использую плагин: http://tutorialzine.com/2010/12/better-confirm-box-jquery-css3/

public static string RenderConfirm(string title, string yes, string no, string deleteMessage)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("<script type=\"text/javascript\" charset=\"utf-8\">");
        sb.AppendLine("$(function () {");
        sb.AppendLine("$('.deletelink').live('click', function (e) {");
        sb.AppendLine("e.preventDefault();");
        sb.AppendLine("var elem = $(this);");
        sb.AppendLine("$.confirm({");
        sb.AppendLine("'title': '" + title + "',");
        //sb.AppendLine("'message': $(this).attr('data-delete-message'),");
        sb.AppendLine("'message': '" + deleteMessage + "',");
        sb.AppendLine("'buttons': {");
        sb.AppendLine("'" + yes + "': {");
        sb.AppendLine("'class': 'confirm-yes',");
        sb.AppendLine("'action': function () {");
        sb.AppendLine("$.post($(elem).attr('href'));");
        sb.AppendLine("}");
        sb.AppendLine("},");
        sb.AppendLine("'" + no + "': {");
        sb.AppendLine("'class': 'confirm-no',");
        sb.AppendLine("'action': function () { } // Nothing to do in this case. You can as well omit the action property.");
        sb.AppendLine("}");
        sb.AppendLine("}");
        sb.AppendLine("});");
        sb.AppendLine("});");
        sb.AppendLine("});");
        sb.AppendLine("</script>");

        return sb.ToString();
    }
1 голос
/ 27 декабря 2011

Если это проблема безопасности, я бы не стал настаивать на этом и анализировать ее на стороне клиента, так как это вообще означает отсутствие безопасности.тот факт, что вы не отображаете определенные столбцы, не означает, что данные недоступны для неавторизованных пользователей.Это может быть легко достигнуто инструментами разработчика из любых браузеров (Firebug) или прокси.

Вы должны убедиться, что пользователи получат только те данные, которые им нужны.Если у вас есть пользователи с различными уровнями разрешений / доступа, вам необходимо реализовать подход RBAC - Role Based Access Control.Затем, исходя из роли, к которой принадлежит конкретный пользователь, вы предоставляете ему данные, которые ему необходимы, и он имеет право.Отсюда вы можете пойти разными путями, чтобы достичь своей цели.Быстрым и грязным способом было бы создать динамический запрос LINQ для выбора только столбцов, которые необходимы для конкретного пользователя, и простую структуру типа switch / case в переменной Role для построения правильного запроса.Более сложным будет создание коллекций имен столбцов для каждой роли и логики фильтрации для общего результата LINQ.Он будет более гибким и позволит легко добавлять / удалять столбцы без необходимости изменять логику.

Это некоторые советы / соображения высокого уровня, поскольку вы не предоставили никакого кода или справки о том, что приложениеи почему это должно работать так.Но опять же, если вы говорите о причинах безопасности для сокрытия данных, не отправляйте их в браузере клиентов в виде простого текста.Кто-то, в конце концов, обнаружит, что вы отправляете полный набор, и он только не обрабатывается.Использование javascript для безопасности никогда не является хорошей идеей, потому что ist все на стороне клиента и может быть изменено во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...