четверг, 23 января 2014 г.

Преобразование JSON и XML в объекты c#

Преобразование строки Json в объект c#

К примеру имеем такой Json :
var jsonStr=@"{
    "one": "value",
    "two": [
        [
            "123",
            "325",
            "string",
            "0.10"
        ],
        [
            "k",
            "1.0",
            "20.04.2004",
            ""
        ]
    ],
    "three": [
        "29",
        "1.0",
        "13.10.2000",
        ""
    ]
}";

Чтобы преобразовать его в объект c# подключаем пространство имен System.Web.Script.Serialization;

Затем создаем класс, описывающий наш объект. В Visual Studio 2012 есть возможность вставить JSON - код как класс, достаточно лишь поместить нужный экземпляр в буфер обмена (скопировать) и в студии нажать Edit - Paste special - Paste JSON as Classes (Правка - Специальная вставка - Вставить JSON как классы):
public class Test
        {
            public string one {get;set;}
            public List<List<string>> two{ get; set; }
            public List<string> three{ get; set; }
        }
И получаем результат двумя строчками:
 var jss = new JavaScriptSerializer();
 var result = jss.Deserialize<Test>(jsonStr));
Кстати, JSONLint - отличный способ проверить и отформатировать ваш Json.


Преобразование строки XML в объект c# 

Имеем такой XML:
var xmlStr=@"<?xml version="1.0" encoding="UTF-8"?>
<Root>
   <One>value</One>
   <Three>
      <element>29</element>
      <element>1.0</element>
      <element>13.10.2000</element>
      <element />
   </Three>
   <Two>
      <element>
         <element>123</element>
         <element>325</element>
         <element>string</element>
         <element>0.10</element>
      </element>
      <element>
         <element>k</element>
         <element>1.0</element>
         <element>20.04.2004</element>
         <element />
      </element>
   </Two>
</Root>";

В Visual Studio 2012 есть возможность вставить XML код как класс, достаточно лишь поместить нужный экземпляр в буфер обмена (скопировать) и в студии нажать Edit - Paste special - Paste XML as Classes (Правка - Специальная вставка - Вставить XML как классы). Проверить свой XML-код можно тут.

Получили следующий класс:
    [XmlTypeAttribute(AnonymousType = true)]
    [XmlRootAttribute(Namespace = "", IsNullable = false)]
    public class Root
    {
        public string One { get; set; }
        [XmlArrayItemAttribute("element", IsNullable = false)]
        public string[] Three { get; set; }
        [XmlArrayItemAttribute("element", IsNullable = false),
XmlArrayItemAttribute("element", IsNullable = false, NestingLevel = 1)]
        public string[][] Two { get; set; }
    }
Преобразовать эту строку XML в объект c# теперь можно, используя следующую функцию:
 public static Root DeserializeFromXML(string xmlStr)
        {
            private var result = "";
            var deserializer = new XmlSerializer(typeof(Root));
            using (var reader = new StringReader(xmlStr))
                result = (Root)deserializer.Deserialize(reader);
         
            return result;
        }
      

среда, 22 января 2014 г.

Visual studio проблема при публикации веб-приложения, пустая папка

Не первый раз натыкаюсь на проблему - при попытке публикации веб-приложения на диск (по-умолчанию в C:\inetpub\wwwroot) в выходных данных пишется что-то вроде:
...
...
...
Публикация каталога /...
Публикация: успешно.

А на деле - создается пустая папка. И вроде бы запустили студию от администратора и права на запись в папку есть. Решить проблему можно, удалив текущий профиль публикации и создав хотя бы точно такой же.

вторник, 21 января 2014 г.

JQuery DataTables баги и фичи

Недавно использовал в ASP.NET приложении библиотеку DataTables для вывода большой таблицы (данные получаются с сервера) и заметил, что информации на русском языке по теме не много, так что решил написать о некоторых нюансах, надеюсь кому-то это поможет сэкономить время. Про основы использования рассказывать не буду, на сайте полно примеров. Поехали.

Проблема №1

Ширина ячеек в заголовке таблицы (в thead) отличается от ширины ячеек в теле таблицы (в tbody) на 1px.

Мне помогло использование вот такого стиля для таблицы.
#myTable {
table-layout: fixed;
margin: 0 auto;
clear: both;
width:100%
}
(ссылка на ответ разработчика библиотеки)

Проблема №2 

При использовании плагина ColVis (предназначен для сокрытия столбцов) в таблице с данными, получаемыми с сервера (server-side processing) - таблица перезагружается полностью, даже если необходимо просто скрыть один столбец.

Решить можно таким способом: находим в ColVis.js следующие строчки и комментируем выделенную.
// Optimisation for server-side processing when scrolling - don't do a full redraw

if ( dt.oFeatures.bServerSide && (dt.oScroll.sX !== "" || dt.oScroll.sY !== "" ) )

{

that.s.dt.oInstance.fnSetColumnVis(i, showHide, false);

that.s.dt.oInstance.fnAdjustColumnSizing(false);

    //that.s.dt.oInstance.oApi._fnScrollDraw(that.s.dt);    that._fnDrawCallback();

}
(ссылка на ответ разработчика библиотеки)

Задача №1

Добавить собственный класс к тегу элемента таблицы

Решение:
var extensions = {
"sPaging": "yourClass",
"sPageButton": "yourClass",
"sPageButtonActive": "yourClass",
"sWrapper": "table_container "
};
$.extend($.fn.dataTableExt.oStdClasses, extensions);
(ссылка на источник)

Задача №2

Переместить элемент таблицы в другой тег ( к примеру информацию о количестве записей вынести в заголовок)

Решение:
oTable = $("#myTable").dataTable({
fnInitComplete: function (oSettings, json) {
$("#table_info").detach().prependTo("#dtInfo");
}});
"table_info" - идентификатор целевого элемента, который нужно переместить, "dtInfo" - тега, куда произойдет перемещение после загрузки таблицы.

(ссылка на источник)

Задача №3

Воздействовать на ячейки таблицы после её загрузки (удалить содержимое, применить стиль и тд).

Решение: Например сделаем шрифт жирным в шестом столбце таблицы.
oTable = $("#myTable").dataTable({
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('td:eq(5)', nRow).css('font-weight', 'bold');
return nRow;
}});

Задача №4 

Сделать ручной ввод отображаемого количества записей на странице.

Изначально в DataTables количество отображаемых записей контролируется выпадающим списком, но мне понадобилось использовать обычное текстовое поле, чтобы в любой момент задать произвольное число. 

Решение: 
function redrawWithNewCount(t, row_count) {
//Lifted more or less right out of the DataTables source
var oSettings = t.fnSettings();
oSettings._iDisplayLength = parseInt(row_count, 10);
t._fnCalculateEnd(oSettings);
/* If we have space to show extra rows (backing up from the end point - then do so */
if (oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay()) {
oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength; if (oSettings._iDisplayStart < 0) {
    oSettings._iDisplayStart = 0;
; }
}
if (oSettings._iDisplayLength == -1) {
    oSettings._iDisplayStart = 0;
} t.fnDraw(oSettings);
return t;
} oTable = $("#myTable").dataTable({
fnInitComplete: function (oSettings, json) {
$("#myTable_length").html("<label>Записей на странице:<input name=\"myTable_length\" aria-controls=\"myTable\" type=\"number\"/></label>");
$("#myTable_length>label>input").val(oTable.fnSettings()._iDisplayLength);
$('#dtLength>label>input').change(function () {
redrawWithNewCount(oTable, this.value);
});
}
});
(ссылка на ответ разработчика, откуда я взял функцию "redrawWithNewCount")