jquery datatables服务器端列
我正在使用jQuery数据表与服务器端C#/ asp.net mvc3处理。它现在一切正常,但我有一个新的任务要做:jquery datatables服务器端列
我想隐藏一些列出于安全原因某些用户。如何在服务器端c#中创建列并传递给视图中的数据表?
控制器可能类似于:
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正确的,但。
/拉塞
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();
}
其很好。我有这个。我想要的是在控制器中生成的aoColumns属性,所以我只发送用户可以看到的列的数据。有些用户看不到Headline列和Headline列的数据,所以我不发送这些数据,但由于aColumns属性,jquery需要两列(不仅仅是创建列) – InfoLearner 2011-12-27 11:34:36
您可以为此编写一个html-helper,逗号分隔值(或类似),并为您生成脚本。 @ Html.DataTable(...) – 2011-12-27 12:58:15
对不起,我不明白。你的意思是“aColumns”:@ Html.GetColumnsForUser(“UserRole”)?我不知道我是否清楚。我想隐藏一列。所以如果一列包含编辑超链接,并且用户不是管理员,那么我想隐藏所有行的此列。如果用户是管理员,那么我想隐藏编辑,当他创建的行由他 – InfoLearner 2011-12-27 13:03:43
如果这是一个安全问题,我不会推动一切,并在客户端解析它,因为这意味着没有任何安全性。您不显示某些列的事实并不意味着未经授权的用户无法使用这些数据。开发人员可以通过任何浏览器(Firebug)或代理轻松访问它。
您需要确保用户只能得到他们需要的数据。如果您拥有不同权限/访问级别的用户,则需要实施RBAC - 基于角色的访问控制方法。然后,根据特定用户所属的角色,向他提供他有资格获得的数据&。从这里你可以走很多路径来达到你的目标。快速和肮脏的方法是创建一个动态的LINQ查询来选择只有特定用户需要的列和角色变量上的简单开关/案例结构来构建正确的查询。 更复杂的需要为每个角色创建列名称集合,并为通用LINQ结果过滤逻辑。它会更灵活,并且可以轻松添加/删除列,而无需更改逻辑。
这些是一些高层次的建议/想法,因为您没有提供关于应用程序的什么代码或背景以及为什么它需要这样工作。但是,如果您正在讨论隐藏数据的安全原因,请不要将其以纯文本格式发送到客户端浏览器。最终有人会发现你正在发送完整的集合,并且它只能被渲染。将javascript用于安全性从来都不是好主意,因为ist全部在客户端,并且可以在运行时进行修改。
简单的答案是一切分配到一个大的JSON对象,然后在客户端解析它。该JSON理想情况下应该有至少列名和数据 – naveen 2011-12-27 02:31:29
我试过了,但没有运气。你的意思是我必须在c#结果JSON中添加columdef或acolum属性,以便查看? – InfoLearner 2011-12-27 02:37:13
请显示您尝试过的以及您目前如何绑定的内容。 – naveen 2011-12-27 02:39:00