protected bool check_object_type(List <Guid> objectIds, PrivacyObjectType objectType)
        {
            switch (objectType)
            {
            case PrivacyObjectType.None:
            case PrivacyObjectType.Node:
            case PrivacyObjectType.NodeType:
            {
                if (objectIds.Count != 1)
                {
                    return(false);
                }

                bool isNodeType = objectType != PrivacyObjectType.Node &&
                                  CNController.is_node_type(paramsContainer.Tenant.Id, objectIds).Count == objectIds.Count;
                bool isNode = !isNodeType && objectType != PrivacyObjectType.NodeType &&
                              CNController.is_node(paramsContainer.Tenant.Id, objectIds).Count == objectIds.Count;

                if (!isNodeType && !isNode)
                {
                    return(false);
                }

                bool accessPermission =
                    AuthorizationManager.has_right(AccessRoleName.ManageOntology, paramsContainer.CurrentUserID);

                if (!accessPermission)
                {
                    accessPermission = CNController.is_service_admin(paramsContainer.Tenant.Id,
                                                                     objectIds[0], paramsContainer.CurrentUserID.Value);
                }

                if (!accessPermission && isNode)
                {
                    accessPermission = CNController.is_node_admin(paramsContainer.Tenant.Id,
                                                                  paramsContainer.CurrentUserID.Value, objectIds[0], null, null, null) ||
                                       PrivacyController.check_access(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID,
                                                                      objectIds[0], PrivacyObjectType.Node, PermissionType.Modify);
                }

                return(accessPermission);
            }

            case PrivacyObjectType.FAQCategory:
                return(QAController.is_faq_category(paramsContainer.Tenant.Id, objectIds).Count == objectIds.Count &&
                       (AuthorizationManager.has_right(AccessRoleName.ManageQA, paramsContainer.CurrentUserID) ||
                        QAController.is_workflow_admin(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID.Value, null)));

            case PrivacyObjectType.QAWorkFlow:
                return(QAController.is_workflow(paramsContainer.Tenant.Id, objectIds).Count == objectIds.Count &&
                       AuthorizationManager.has_right(AccessRoleName.ManageQA, paramsContainer.CurrentUserID));

            case PrivacyObjectType.Poll:
                return(FGController.is_poll(paramsContainer.Tenant.Id, objectIds).Count == objectIds.Count &&
                       AuthorizationManager.has_right(AccessRoleName.ManagePolls, paramsContainer.CurrentUserID));

            case PrivacyObjectType.Report:
                return(!objectIds.Any(u => !ReportUtilities.ReportIDs.Any(x => x.Value == u)) &&
                       PublicMethods.is_system_admin(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID.Value));

            case PrivacyObjectType.FormElement:
                return(FGController.is_form_element(paramsContainer.Tenant.Id, objectIds).Count == objectIds.Count &&
                       AuthorizationManager.has_right(AccessRoleName.ManageForms, paramsContainer.CurrentUserID));
            }

            return(false);
        }
        protected void check_access(List <Guid> objectIds, PrivacyObjectType objectType,
                                    List <PermissionType> permissions, ref string responseText)
        {
            //Privacy Check: OK
            if (!paramsContainer.GBView)
            {
                return;
            }

            if (permissions.Count > 0)
            {
                permissions = permissions.Where(p => p != PermissionType.None).ToList();
            }

            Dictionary <Guid, List <PermissionType> > results = objectType == PrivacyObjectType.None ?
                                                                new Dictionary <Guid, List <PermissionType> >() : (permissions.Count == 0 ?
                                                                                                                   PrivacyController.check_access(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID, objectIds, objectType) :
                                                                                                                   PrivacyController.check_access(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID, objectIds, objectType, permissions));

            responseText = "{" + string.Join(",", results.Keys.Select(
                                                 k => "\"" + k + "\":[" + string.Join(",", results[k].Select(p => "\"" + p.ToString() + "\"")) + "]")) + "}";
        }
        public void ProcessRequest(HttpContext context)
        {
            //Privacy Check: OK
            paramsContainer = new ParamsContainer(context, nullTenantResponse: true);
            if (!paramsContainer.ApplicationID.HasValue)
            {
                return;
            }

            string responseText = string.Empty;

            string command = PublicMethods.parse_string(context.Request.Params["Command"], false);

            if (string.IsNullOrEmpty(command))
            {
                return;
            }

            Guid currentUserId = paramsContainer.CurrentUserID.HasValue ? paramsContainer.CurrentUserID.Value : Guid.Empty;

            Guid        fileId = string.IsNullOrEmpty(context.Request.Params["FileID"]) ? Guid.Empty : Guid.Parse(context.Request.Params["FileID"]);
            DocFileInfo file   = DocumentsController.get_file(paramsContainer.Tenant.Id, fileId);

            if (file == null)
            {
                paramsContainer.return_response(PublicConsts.BadRequestResponse);
                return;
            }

            bool isTemporary =
                PublicMethods.parse_string(HttpContext.Current.Request.Params["Category"], false).ToLower() == "temporary";

            bool hasAccess = isTemporary || PublicMethods.is_system_admin(paramsContainer.Tenant.Id, currentUserId);

            PrivacyObjectType pot = file.OwnerType == FileOwnerTypes.Node ? PrivacyObjectType.Node : PrivacyObjectType.None;

            hasAccess = hasAccess || PrivacyController.check_access(paramsContainer.Tenant.Id,
                                                                    paramsContainer.CurrentUserID, file.OwnerID.Value, pot, PermissionType.View);

            if (!hasAccess && currentUserId != Guid.Empty &&
                CNController.is_node(paramsContainer.Tenant.Id, file.OwnerID.Value))
            {
                bool isCreator = false, isContributor = false, isExpert = false, isMember = false, isAdminMember = false,
                     isServiceAdmin = false, isAreaAdmin = false, perCreatorLevel = false;

                CNController.get_user2node_status(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID.Value,
                                                  file.OwnerID.Value, ref isCreator, ref isContributor, ref isExpert, ref isMember, ref isAdminMember,
                                                  ref isServiceAdmin, ref isAreaAdmin, ref perCreatorLevel);

                hasAccess = isServiceAdmin || isAreaAdmin || isCreator || isContributor || isExpert || isMember;
            }

            if (!hasAccess)
            {
                paramsContainer.return_response("{\"ErrorText\":\"" + Messages.AccessDenied.ToString() + "\"}");
            }

            if (isTemporary)
            {
                file.FolderName = FolderNames.TemporaryFiles;
            }
            else
            {
                file.refresh_folder_name();
            }

            if (!file.exists(paramsContainer.Tenant.Id))
            {
                _return_response(ref responseText);
            }

            DocFileInfo destFile = new DocFileInfo()
            {
                FileID = file.FileID, FolderName = FolderNames.PDFImages
            };

            switch (command)
            {
            case "Convert2Image":
                convert2image(file,
                              PublicMethods.parse_string(context.Request.Params["PS"]),
                              destFile,
                              PublicMethods.parse_bool(context.Request.Params["Repair"]), ref responseText);
                _return_response(ref responseText);
                return;

            case "GetPagesCount":
                get_pages_count(file,
                                PublicMethods.parse_string(context.Request.Params["PS"]),
                                destFile, ref responseText);
                _return_response(ref responseText);
                return;

            case "GetPage":
                get_page(PublicMethods.parse_int(context.Request.Params["Page"], 1), destFile);
                return;
            }

            paramsContainer.return_response(PublicConsts.BadRequestResponse);
        }
Example #4
0
        private static List <SearchDoc> process_search_results(Guid applicationId, List <SearchDoc> listDocs,
                                                               Guid?currentUserId, ref List <SearchDoc> toBeRemoved, int count)
        {
            List <DocFileInfo> files = new List <DocFileInfo>();

            Dictionary <SearchDocType, List <Guid> > existingObjs = get_existing_ids(applicationId, listDocs, ref files);

            listDocs.Where(doc => files.Any(u => u.FileID == doc.ID)).ToList().ForEach(doc =>
            {
                doc.FileInfo = files.Where(u => u.FileID == doc.ID).FirstOrDefault();
            });

            List <Guid> existingIds = new List <Guid>();

            //Remove not existing docs
            foreach (SearchDoc sd in listDocs)
            {
                if (!existingObjs.Any(x => x.Value.Any(z => z == sd.ID)))
                {
                    toBeRemoved.Add(sd);
                }
            }
            //end of Remove not existing docs

            List <Guid> granted = new List <Guid>();

            //Check access to nodes
            List <Guid> nodeIdsToCheckAccess = new List <Guid>();
            List <Guid> idsToCheckAccess     = new List <Guid>();

            if (existingObjs.ContainsKey(SearchDocType.Node))
            {
                nodeIdsToCheckAccess.AddRange(existingObjs[SearchDocType.Node]);
            }
            if (existingObjs.ContainsKey(SearchDocType.File))
            {
                existingObjs[SearchDocType.File].ForEach(f =>
                {
                    SearchDoc fl = listDocs.Where(x => x.ID == f && x.FileInfo != null &&
                                                  x.FileInfo.OwnerNodeID.HasValue).FirstOrDefault();
                    if (fl == null)
                    {
                        return;
                    }

                    if (!nodeIdsToCheckAccess.Any(a => a == fl.FileInfo.OwnerNodeID))
                    {
                        nodeIdsToCheckAccess.Add(fl.FileInfo.OwnerNodeID.Value);
                    }

                    if (fl.FileInfo.OwnerID.HasValue && fl.FileInfo.OwnerID != fl.FileInfo.OwnerNodeID)
                    {
                        if (!idsToCheckAccess.Any(a => a == fl.FileInfo.OwnerID))
                        {
                            idsToCheckAccess.Add(fl.FileInfo.OwnerID.Value);
                        }
                    }

                    if (fl.FileInfo.OwnerID.HasValue && fl.FileInfo.OwnerID != fl.FileInfo.OwnerNodeID &&
                        !idsToCheckAccess.Any(a => a == fl.FileInfo.OwnerID))
                    {
                        idsToCheckAccess.Add(fl.FileInfo.OwnerID.Value);
                    }
                });
            }

            List <PermissionType> pts = new List <PermissionType>();

            pts.Add(PermissionType.View);
            pts.Add(PermissionType.ViewAbstract);
            pts.Add(PermissionType.Download);

            Dictionary <Guid, List <PermissionType> > ps = PrivacyController.check_access(applicationId,
                                                                                          currentUserId, nodeIdsToCheckAccess, PrivacyObjectType.Node, pts);

            granted.AddRange(ps.Keys.Where(
                                 k => ps[k].Any(p => p == PermissionType.ViewAbstract || p == PermissionType.View)));

            List <Guid> grantedFileOwners = PrivacyController.check_access(applicationId,
                                                                           currentUserId, idsToCheckAccess, PrivacyObjectType.None, PermissionType.View);

            listDocs.Where(d => d.SearchDocType == SearchDocType.File && d.FileInfo != null &&
                           d.FileInfo.OwnerNodeID.HasValue).ToList().ForEach(doc =>
            {
                Guid ndId = doc.FileInfo.OwnerNodeID.Value;

                bool isGranted = ps.ContainsKey(ndId) && ps[ndId].Any(u => u == PermissionType.View) &&
                                 ps[ndId].Any(u => u == PermissionType.Download);

                if (isGranted && doc.FileInfo.OwnerID.HasValue && doc.FileInfo.OwnerID != ndId &&
                    !grantedFileOwners.Any(o => o == doc.FileInfo.OwnerID))
                {
                    isGranted = false;
                }

                doc.AccessIsDenied = !isGranted;
            });
            //end of Check access to nodes

            //Check access to other objects
            List <Guid> ids = new List <Guid>();

            existingObjs.Keys.Where(x => x != SearchDocType.Node).ToList()
            .ForEach(u => ids.AddRange(existingObjs[u]));

            granted.AddRange(PrivacyController.check_access(applicationId,
                                                            currentUserId, ids, PrivacyObjectType.None, PermissionType.View));
            //end of Check access to other objects

            //Check permissions
            bool forceCheckPermission = RaaiVanSettings.IndexUpdate.CheckPermissions(applicationId);

            existingObjs.Keys.ToList().ForEach(k =>
            {
                existingObjs[k].ForEach(id =>
                {
                    SearchDoc doc = listDocs.Where(d => d.ID == id).FirstOrDefault();
                    if (doc == null)
                    {
                        return;
                    }

                    bool isGranted = doc.AccessIsDenied.HasValue && doc.AccessIsDenied.Value ?
                                     false : granted.Any(x => x == id);

                    if (!isGranted)
                    {
                        doc.AccessIsDenied = true;
                    }

                    if (isGranted || !forceCheckPermission)
                    {
                        existingIds.Add(id);
                    }
                });
            });
            //end of Check permissions

            return(listDocs.Where(doc => existingIds.Any(x => x == doc.ID))
                   .Take(Math.Min(count, listDocs.Count)).ToList());
        }
        public void ProcessRequest(HttpContext context)
        {
            //Privacy Check: OK
            paramsContainer = new ParamsContainer(context, nullTenantResponse: false);

            Guid fileId = string.IsNullOrEmpty(context.Request.Params["FileID"]) ?
                          Guid.Empty : Guid.Parse(context.Request.Params["FileID"]);

            if (fileId == Guid.Empty && !Guid.TryParse(context.Request.Params["ATTFID"], out fileId))
            {
                fileId = Guid.Empty;
            }

            string category = PublicMethods.parse_string(context.Request.Params["Category"], false);

            bool   isTemporary = category.ToLower() == FolderNames.TemporaryFiles.ToString().ToLower();
            bool?  addFooter   = PublicMethods.parse_bool(context.Request.Params["Meta"]);
            Guid?  coverId     = PublicMethods.parse_guid(context.Request.Params["CoverID"]);
            string pdfPassword = PublicMethods.parse_string(context.Request.Params["PS"]);

            List <FolderNames> freeFolders = new[] {
                FolderNames.ProfileImages,
                FolderNames.HighQualityProfileImage,
                FolderNames.CoverPhoto,
                FolderNames.HighQualityCoverPhoto,
                FolderNames.Icons,
                FolderNames.HighQualityIcon,
                FolderNames.ApplicationIcons,
                FolderNames.HighQualityApplicationIcon,
                FolderNames.Pictures
            }.ToList();

            bool isFreeFolder = !string.IsNullOrEmpty(category) && freeFolders.Any(f => f.ToString().ToLower() == category.ToLower());

            if (isFreeFolder)
            {
                FolderNames fn = freeFolders.Where(u => u.ToString().ToLower() == category.ToLower()).FirstOrDefault();

                DocFileInfo pic =
                    new DocFileInfo()
                {
                    FileID = fileId, Extension = "jpg", FileName = fileId.ToString(), FolderName = fn
                };

                send_file(pic, false);
            }

            if (!paramsContainer.ApplicationID.HasValue)
            {
                paramsContainer.return_response(PublicConsts.NullTenantResponse);
                return;
            }

            if (isTemporary)
            {
                string ext = PublicMethods.parse_string(context.Request.Params["Extension"]);

                DocFileInfo temp = new DocFileInfo()
                {
                    FileID     = fileId,
                    Extension  = ext,
                    FileName   = fileId.ToString(),
                    FolderName = FolderNames.TemporaryFiles
                };

                send_file(temp, false);
            }
            else
            {
                DocFileInfo AttachFile = DocumentsController.get_file(paramsContainer.Tenant.Id, fileId);

                if (AttachFile == null)
                {
                    paramsContainer.return_response("{\"ErrorText\":\"" + Messages.AccessDenied + "\"}");
                    return;
                }

                PrivacyObjectType pot = AttachFile.OwnerType == FileOwnerTypes.Node ?
                                        PrivacyObjectType.Node : PrivacyObjectType.None;

                DocFileInfo ownerNode = !AttachFile.FileID.HasValue ? null :
                                        DocumentsController.get_file_owner_node(paramsContainer.Tenant.Id, AttachFile.FileID.Value);
                if (ownerNode != null)
                {
                    AttachFile.OwnerNodeID   = ownerNode.OwnerNodeID;
                    AttachFile.OwnerNodeName = ownerNode.OwnerNodeName;
                    AttachFile.OwnerNodeType = ownerNode.OwnerNodeType;
                }

                bool accessDenied =
                    !PrivacyController.check_access(paramsContainer.Tenant.Id,
                                                    paramsContainer.CurrentUserID, AttachFile.OwnerID.Value, pot, PermissionType.View) &&
                    !(
                        paramsContainer.CurrentUserID.HasValue &&
                        new CNAPI()
                {
                    paramsContainer = this.paramsContainer
                }
                        ._is_admin(paramsContainer.Tenant.Id, AttachFile.OwnerID.Value,
                                   paramsContainer.CurrentUserID.Value, CNAPI.AdminLevel.Creator, false)
                        );

                if (accessDenied)
                {
                    //Save Log
                    try
                    {
                        LogController.save_log(paramsContainer.Tenant.Id, new Log()
                        {
                            UserID           = paramsContainer.CurrentUserID,
                            HostAddress      = PublicMethods.get_client_ip(HttpContext.Current),
                            HostName         = PublicMethods.get_client_host_name(HttpContext.Current),
                            Action           = Modules.Log.Action.Download_AccessDenied,
                            SubjectID        = fileId,
                            Info             = "{\"Error\":\"" + Base64.encode(Messages.AccessDenied.ToString()) + "\"}",
                            ModuleIdentifier = ModuleIdentifier.DCT
                        });
                    }
                    catch { }
                    //end of Save Log

                    paramsContainer.return_response("{\"ErrorText\":\"" + Messages.AccessDenied + "\"}");

                    return;
                }

                AttachFile.refresh_folder_name();

                string ext = AttachFile == null || string.IsNullOrEmpty(AttachFile.Extension) ? string.Empty :
                             AttachFile.Extension.ToLower();
                bool isImage = ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "gif" || ext == "bmp";

                if (string.IsNullOrEmpty(AttachFile.Extension) || AttachFile.Extension.ToLower() != "pdf")
                {
                    coverId = null;
                }

                bool   dl          = !isImage || PublicMethods.parse_bool(context.Request.Params["dl"], defaultValue: true) == true;
                string contentType = !dl && isImage?PublicMethods.get_mime_type_by_extension(ext) : null;

                send_file(AttachFile, !isImage, addPDFCover: true,
                          addPDFFooter: addFooter.HasValue && addFooter.Value,
                          coverId: coverId,
                          pdfPassword: pdfPassword,
                          contentType: contentType,
                          isAttachment: dl);
            }
        }
        protected void get_report(ModuleIdentifier moduleIdentifier, string reportName, bool excel, bool rtl,
                                  bool isPersian, ref Dictionary <string, string> dic, int pageNumber, int pageSize, ref string responseText,
                                  List <ReportParameter> parameters, string password)
        {
            //Privacy Check: OK
            if (!paramsContainer.GBEdit)
            {
                return;
            }

            bool isSystemAdmin =
                PublicMethods.is_system_admin(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID.Value);

            Guid?reportId = ReportUtilities.get_report_id(moduleIdentifier, reportName);

            bool hasAccess = reportId.HasValue && (isSystemAdmin ||
                                                   AuthorizationManager.has_right(AccessRoleName.Reports, paramsContainer.CurrentUserID));

            hasAccess = hasAccess && (isSystemAdmin ||
                                      PrivacyController.check_access(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID,
                                                                     reportId.Value, PrivacyObjectType.Report, PermissionType.View));

            if (!hasAccess)
            {
                responseText = "{\"ErrorText\":\"" + Messages.AccessDenied + "\"}";
                return;
            }

            DataTable tbl     = new DataTable();
            string    actions = string.Empty;

            Dictionary <string, string> columnsDic = new Dictionary <string, string>();

            ReportsController.get_report(paramsContainer.Tenant.Id,
                                         moduleIdentifier, reportName, ref tbl, ref actions, ref columnsDic, parameters);

            int firstRow = excel ? 0 : (pageSize * (pageNumber - 1));
            int lastRow  = (excel ? tbl.Rows.Count : Math.Min(firstRow + pageSize, tbl.Rows.Count)) - 1;

            for (int c = 0; c < tbl.Columns.Count; ++c)
            {
                if (tbl.Columns[c].DataType != typeof(string) || tbl.Columns[c].ColumnName.IndexOf("_HTML") < 0)
                {
                    continue;
                }

                tbl.Columns[c].ColumnName = tbl.Columns[c].ColumnName.Replace("_HTML", string.Empty);

                for (int r = firstRow; r <= lastRow; ++r)
                {
                    if (tbl.Rows[r][c] != DBNull.Value && !string.IsNullOrEmpty((string)tbl.Rows[r][c]))
                    {
                        //tbl.Rows[r][c] = PublicMethods.markup2plaintext(
                        //Expressions.replace((string)tbl.Rows[r][c], Expressions.Patterns.HTMLTag, " ")).Trim();

                        string str = (string)tbl.Rows[r][c];
                        str = Expressions.replace(str, Expressions.Patterns.HTMLTag, " ");
                        str = PublicMethods.markup2plaintext(paramsContainer.Tenant.Id, str).Trim();

                        tbl.Rows[r][c] = str;
                    }
                }
            }

            if (excel)
            {
                try
                {
                    Dictionary <string, bool> usedColNames = new Dictionary <string, bool>();

                    foreach (string n in dic.Values)
                    {
                        usedColNames[n] = true;
                    }

                    for (int c = 0; c < tbl.Columns.Count; ++c)
                    {
                        if (columnsDic.ContainsKey(tbl.Columns[c].ColumnName))
                        {
                            string colName = columnsDic[tbl.Columns[c].ColumnName];
                            int    num     = 1;
                            while (true)
                            {
                                string tmpName = colName + (num <= 1 ? string.Empty : " (" + num.ToString() + ")");

                                if (!usedColNames.ContainsKey(tmpName))
                                {
                                    usedColNames[tmpName] = true;
                                    colName = tmpName;
                                    break;
                                }
                                else
                                {
                                    ++num;
                                }
                            }

                            tbl.Columns[c].ColumnName = colName;
                        }

                        bool isString = tbl.Columns[c].DataType == typeof(string);
                        bool isDic    = tbl.Columns[c].ColumnName.IndexOf("_Dic") >= 0;

                        if (isString && isDic)
                        {
                            Dictionary <string, string> colDic = _get_dictionary(tbl.Columns[c].ColumnName);

                            for (int r = 0; r < tbl.Rows.Count; ++r)
                            {
                                bool isNull = tbl.Rows[r].ItemArray[c] == DBNull.Value || tbl.Rows[r].ItemArray[c] == null;

                                if (!isNull && colDic.ContainsKey((string)tbl.Rows[r].ItemArray[c]))
                                {
                                    tbl.Rows[r][c] = colDic[(string)tbl.Rows[r].ItemArray[c]];
                                }
                            }
                        }

                        if (isDic)
                        {
                            tbl.Columns[c].ColumnName = tbl.Columns[c].ColumnName.Replace("_Dic", string.Empty);
                        }
                    }

                    //meta data for exported file
                    Privacy p = !reportId.HasValue ? null :
                                PrivacyController.get_settings(paramsContainer.Tenant.Id, reportId.Value);
                    string confidentiality = p == null ? null : p.Confidentiality.Title;

                    User currentUser = !paramsContainer.CurrentUserID.HasValue ? null :
                                       UsersController.get_user(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID.Value);
                    if (currentUser == null)
                    {
                        currentUser = new User();
                    }
                    DownloadedFileMeta meta = new DownloadedFileMeta(PublicMethods.get_client_ip(HttpContext.Current),
                                                                     currentUser.UserName, currentUser.FirstName, currentUser.LastName, confidentiality);
                    //end of meta data for exported file

                    string reportFileName = "Reports_" + PublicMethods.get_random_number().ToString();

                    ExcelUtilities.ExportToExcel(reportFileName, tbl, rtl, dic, password, meta);
                }
                catch (Exception ex)
                {
                    responseText = "{\"ErrorText\":\"" + Messages.OperationFailed + "\"}";

                    LogController.save_error_log(paramsContainer.Tenant.Id, paramsContainer.CurrentUserID,
                                                 "ExportReportToExcel", ex, ModuleIdentifier.RPT, LogLevel.Fatal);
                }

                return;
            }

            Dictionary <string, bool> isFloatDic = new Dictionary <string, bool>();

            responseText = "{\"Columns\":[";

            for (int i = 0, lnt = tbl.Columns.Count; i < lnt; ++i)
            {
                object obj = null;
                for (int j = firstRow; j <= lastRow; ++j)
                {
                    if (tbl.Rows[j][i] != DBNull.Value && tbl.Rows[j][i] != null && !string.IsNullOrEmpty(tbl.Rows[j][i].ToString()))
                    {
                        obj = tbl.Rows[j][i];
                        break;
                    }
                }

                bool isNumber = false;
                bool isFloat  = false;
                if (obj != null)
                {
                    var objType = obj.GetType();
                    isNumber = objType == typeof(int) || objType == typeof(long) ||
                               objType == typeof(float) || objType == typeof(double) || objType == typeof(decimal);
                    isFloat = objType == typeof(float) || objType == typeof(double) || objType == typeof(decimal);
                }

                isFloatDic.Add(tbl.Columns[i].ColumnName, isFloat);

                string colTitle = columnsDic.ContainsKey(tbl.Columns[i].ColumnName) ?
                                  columnsDic[tbl.Columns[i].ColumnName] : tbl.Columns[i].ColumnName;

                responseText += (i == 0 ? string.Empty : ",") + "{\"ID\":\"" + tbl.Columns[i].ColumnName +
                                "\",\"Title\":\"" + Base64.encode(colTitle) + "\",\"Encoded\":true" +
                                ",\"IsNumber\":" + isNumber.ToString().ToLower() + "}";
            }

            responseText += "],\"Total\":" + tbl.Rows.Count.ToString() + ",\"Rows\":[";

            for (int i = firstRow; i <= lastRow; ++i)
            {
                responseText += (i == firstRow ? string.Empty : ",") + "{";
                for (int j = 0, _ln = tbl.Columns.Count; j < _ln; ++j)
                {
                    if (isFloatDic[tbl.Columns[j].ColumnName])
                    {
                        tbl.Rows[i].ItemArray[j] =
                            Math.Round(double.Parse((tbl.Rows[i].ItemArray[j] == DBNull.Value ? 0 : tbl.Rows[i].ItemArray[j]).ToString()), 2);
                    }

                    string strVal = tbl.Rows[i].ItemArray[j].GetType() == typeof(DateTime) ?
                                    PublicMethods.get_local_date((DateTime)tbl.Rows[i].ItemArray[j], true) :
                                    (isFloatDic[tbl.Columns[j].ColumnName] ?
                                     Math.Round(double.Parse((tbl.Rows[i].ItemArray[j] == DBNull.Value ? 0 : tbl.Rows[i].ItemArray[j]).ToString()), 2) :
                                     tbl.Rows[i].ItemArray[j]).ToString();

                    responseText += (j == 0 ? string.Empty : ",") + "\"" + tbl.Columns[j].ColumnName + "\":\"" + Base64.encode(strVal) + "\"";
                }
                responseText += "}";
            }

            responseText += "],\"Actions\":" + (string.IsNullOrEmpty(actions) ? "{}" : actions) + "}";
        }