воскресенье, 13 сентября 2009 г.

С Днем Программиста!

Желаю всем побольше интересных задач, идей, красивого и качественного кода, ненадоедающей работы и множества возможностей реализовать себя!
Успехов ;-)

четверг, 10 сентября 2009 г.

ASP.NET MVC: jQuery Grid Plugin

Набросал небольшую статью.
Показал как прикрутить и отобразить данные с помощью плагина jqGrid, в дальнейшем планирую рассмотреть сценарии CRUD и различные типы входящих данных.

воскресенье, 30 августа 2009 г.

ASP.NET MVC: ActionLink with Image

Занадобилась мне ссылка с картинкой вместо текста, те ActionLink с картинкой вместо текста.


Попытки передать вместо текста ссылки готовый тег '<img src='Icons/edit.png'/>' ни к чему хорошему не привели, потому как оно выводится через метод HttpUtility.HtmlEncode, который заменяет в тексте знаки '<' '>' на '&lt;' и '&gt;' соответственно.
Сделал с помощью Extension methods (методы-расширения) для класса HtmlHelper.

    public static class Extensions

    {

        public static string ActionLinkImage(this HtmlHelper htmlHelper, string altImageText, string imagePath, string actionName)

        {

            return ActionLinkImage(htmlHelper, altImageText, imagePath, actionName, new RouteValueDictionary(), new RouteValueDictionary());

        }

 

        public static string ActionLinkImage(this HtmlHelper htmlHelper, string altImageText, string imagePath, string actionName, object routeValues)

        {

            return ActionLinkImage(htmlHelper, altImageText, imagePath, actionName, new RouteValueDictionary(routeValues), new RouteValueDictionary());

        }

 

        public static string ActionLinkImage(this HtmlHelper htmlHelper, string altImageText, string imagePath, string actionName, object routeValues, object htmlAttributes)

        {

            return ActionLinkImage(htmlHelper, altImageText, imagePath, actionName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));

        }

 

        public static string ActionLinkImage(this HtmlHelper htmlHelper, string altImageText, string imagePath, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)

        {

            const string linkTextReplacement = "F14E9A0EB8C4";

            string actionLink = System.Web.Mvc.Html.LinkExtensions.ActionLink(htmlHelper, linkTextReplacement, actionName, routeValues,htmlAttributes);

 

            return actionLink.Replace(linkTextReplacement, String.Format(@"<img src='{0}' alt='{1}'/>", imagePath, altImageText));

        }

    }



А применяется оно так:
'<%= Html.ActionLinkImage("Edit", "Icons/edit.png", "Edit", new { id = item.EmployeeId }, new {@class = "ImageLink"})%'>
Результат:
'<A class=ImageLink href="about:/Employee/Edit/100"><IMG alt=Edit src="about:Icons/edit.png">'</A>

суббота, 29 августа 2009 г.

Silverlight: SketchFlow для прототипирования интерфейсов

Очень интересная статья с примером использования SketchFlow для создания прототипов приложения. И перевод на русский Владимира Юнева.

пятница, 28 августа 2009 г.

ASP.NET MVC: DropDownList

При редактировании некоторых полей объекта очень часто необходимо использование контрола DropDownList. А чтоб его заполнить данными нужен объект типа IEnumerable.

Для примера понадобятся слудующие сущности EmployeeEntity, JobEntity

public class EmployeeEntity
  {
    public virtual int EmployeeId { get; set;}
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual String JobId { get; set; }
  }


* This source code was highlighted with Source Code Highlighter.


public class JobEntity
  {
    public virtual string JobId { get; set; }
    public virtual string JobTitle { get; set; }
  }


* This source code was highlighted with Source Code Highlighter.


Что бы удобно передать во View модель данных содержащую как экземпляр Employee так и список Job`ов создаем класс обертку:
public class EmployeeEditViewData
  {
    public EmployeeEntity Employee;
    public IEnumerable<SelectListItem> Jobs;
  }


* This source code was highlighted with Source Code Highlighter.


Теперь необходимо создать Action для Employee контроллера
  1. public ActionResult Edit(int id)
  2.     {
  3.       EmployeeEntity employeeEntity = _employeeRepository.EditById(id);
  4.       IEnumerable<SelectListItem> jobs =
  5.         Domain
  6.         .CurrentSession
  7.         .CreateCriteria<Job>()
  8.         .List<Job>()
  9.         .Select(j => new SelectListItem
  10.                  {
  11.                    Text = j.JobTitle,
  12.                    Value = j.JobId,
  13.                    Selected = employeeEntity.JobId == j.JobId
  14.                  });
  15.  
  16.       EmployeeEditViewData viewData = new EmployeeEditViewData
  17.                         {
  18.                           Employee = employeeEntity,
  19.                           Jobs = jobs
  20.                         };
  21.       return View("Edit", viewData);
  22.     }
* This source code was highlighted with Source Code Highlighter.

А теперь по порядку:
строка 3 - получение экземляра объекта EmployeeEntity;
строки 4-14 - получение экземляра IEnumerable Jobs;
строки 16-20 - создаем EmployeeEditViewData и инициализируем поля ранее получеными объектами;

Для данного action необходимо создать строго типизированную view на основе класса EmployeeEditViewData. У меня студийный генератор не смог сгенерить заготовку view для редактирования полей, но ничего не мешает это сделать самому.
Для поля в котором нам понадобится DropDownList пишем следующий код:
    <p>
      <label for="JobId">
        Job:</label>     
      <%= Html.DropDownList("JobId",Model.Jobs) %>      
    </p>


* This source code was highlighted with Source Code Highlighter.


В общем то все.

четверг, 20 августа 2009 г.

ASP.NET + NHibernate + Oracle и Pagination

Постраничный вывод в ASP.NET + NHibernate + Oracle.
Выдергивать из базы данные постранично желание отнюдь не запретное, посему решено было его удовлетворить.

public class InsuredController : Controller
  {
    private ISessionFactory _SessionFactory;  

    private int? currentPage=0;
    private int pageSize=25;

    //...

    public ActionResult Index(int? pageNumber)
    {      
      currentPage = pageNumber??0;

      ICriteria creteria = _SessionFactory.OpenSession().CreateCriteria(typeof(Foo.FooEntity));
      
      creteria.SetFirstResult(pageSize * (int)currentPage).SetMaxResults(pageSize);
      
      ViewResult vresult = View(creteria.List<Foo.FooEntity>());
      vresult.ViewData["PageNumber"] = pageNumber;
      return vresult;
    }
}

* This source code was highlighted with Source Code Highlighter.


Все бы хорошо, но дальше 0 страницы данные не возвращаются, а все потому что в базу уходит запрос
SELECT  *
 FROM  (SELECT  this_.ID AS ID1_0_0_,
          this_.CREATE_DATE AS CREATE2_0_0_,
          this_.DISABLE_DATE AS DISABLE3_0_0_,
          this_.EDIT_DATE AS EDIT4_0_0_,
          this_.EXCHANG_STAT AS EXCHANG5_0_0_
      FROM  FOO this_)
WHERE  ROWNUM BETWEEN 25 AND 75


* This source code was highlighted with Source Code Highlighter.


А вот оно что - BETWEEN vs ROWNUM.
А в школьном курсе оракловой физики четко написано что ROWNUM - это псевдостолбец, значение которого присваивается строке уже после выполнения предикатов запроса, но перед выполнением сортировок и агрегирований. В то же время оператор BETWEEN ограничивает выборку по столбцу значение которого еще не было присвоено, те равно NULL. А все операции сравнения чего либо с значением NULL = FALSE. Вот и получаем пустой результат.

Решение этой проблемы простое - заменить в конфиге значение своейства dialect - NHibernate.Dialect.OracleDialect на NHibernate.Dialect.Oracle10gDialect или NHibernate.Dialect.Oracle9iDialect

Результирующий запрос:
SELECT  *
 FROM  (SELECT  row_.*, ROWNUM rownum_
      FROM  (SELECT  this_.ID AS ID1_0_0_,
               this_.CREATE_DATE AS CREATE2_0_0_,
               this_.DISABLE_DATE AS DISABLE3_0_0_,
               this_.EDIT_DATE AS EDIT4_0_0_,
               this_.EXCHANG_STAT AS EXCHANG5_0_0_
           FROM  FOO this_) row_
      WHERE  ROWNUM <= :p0)
WHERE  rownum_ > :p1


* This source code was highlighted with Source Code Highlighter.

понедельник, 8 июня 2009 г.

.NET: Отладка приложений / сервисов

Замечательная штука отладчик. Не раз задумывался над проблемой отладки куска кода выполняемого при запуске приложения или сервиса. И вот нашел решение.
Вставляем код там где нужно зацепиться отладчиком, как только среда выполнения выполнит его появиться любимый диалог.


C#:
if (!Debugger.IsAttached) Debugger.Break();
* This source code was highlighted with Source Code Highlighter.

VB.NET:
If Not Debugger.IsAttached Then
  Debugger.Break()
End If

* This source code was highlighted with Source Code Highlighter.

среда, 3 июня 2009 г.

ORACLE: Перемещение таблиц и индексов пользователя в другой tablespace

собственно ответ на вопросы:
How to move LOB data to another tablespace?
How to move user tables to a different tablespace?
How to move user indexes to a different tablespace?

скрипт пока не умеет перемещать индекс-таблицы и секционированные таблицы.

  1. DECLARE
  2.   table_ts_name  VARCHAR2 (30) := 'USER_DATA'; –- табличное пространство для перемещения таблиц
  3.   index_ts_name  VARCHAR2 (30) := 'USER_INDEX'; –- табличное пространство для перемещения индексов
  4.   varUser VARCHAR2(30) := 'HR'; – схема объекты которой необходимо переместить
  5. BEGIN
  6.   FOR obj
  7.   IN ( -- перемещение таблиц содержащих поля LOB типов
  8.     SELECT 'alter table '||owner||'.'|| table_name||' move lob('|| column_name 
  9.         ||') store as (tablespace '|| table_ts_name move_sql
  10.      FROM  dba_tab_cols
  11.     WHERE  owner=varUser and data_type='%LOB'
  12.     UNION ALL
  13.     -- перемещение остальных таблиц   
  14.     SELECT 'alter table '||t1.owner|| '.'||t1.object_name||' move tablespace '||table_ts_name move_sql
  15.      FROM all_objects t1
  16.     WHERE t1.owner=varUser
  17.        AND t1.object_type = 'TABLE'
  18.        AND t1.temporary = 'N'
  19.        AND NOT EXISTS (
  20.                 SELECT 1 from dba_tab_cols t2
  21.                 where t1.owner = t2.owner
  22.                 AND t1.object_name = t2.table_name
  23.                 AND t2.data_type = 'LONG'
  24.                 AND t2.data_type = 'LONG RAW')
  25.     UNION ALL
  26.     -- перемещение и ребилд индексов, за исключением IOT индексов
  27.     SELECT 'alter index '||owner||'.'|| index_name|| ' rebuild tablespace '|| index_ts_name move_sql
  28.      FROM  all_indexes
  29.     WHERE  owner=varUser AND index_type <> 'IOT - TOP')
  30.   LOOP
  31.   dbms_output.put_line(obj.move_sql);
  32.    EXECUTE IMMEDIATE obj.move_sql;
  33.   END LOOP;
  34. END;
* This source code was highlighted with Source Code Highlighter.

понедельник, 1 июня 2009 г.

DateTime.ToString и "/" подстава

задолбался
      DateTime dt = DateTime.Now;
      Trace.WriteLine("ToString() - " + dt.ToString());
      Trace.WriteLine("dd/MM/yyyy HH:mm - " + dt.ToString("dd/MM/yyyy HH:mm"));
      Trace.WriteLine("dd[MM[yyyy HH^mm - " + dt.ToString("dd[MM[yyyy HH^mm"));
      Trace.WriteLine(@"dd\/MM\/yyyy HH:mm - " + dt.ToString(@"dd\/MM\/yyyy HH:mm"));
      Trace.WriteLine("System.Globalization.DateTimeFormatInfo.CurrentInfo.DateSeparator - " +
        System.Globalization.DateTimeFormatInfo.CurrentInfo.DateSeparator);


* This source code was highlighted with Source Code Highlighter.


Output:
ToString() - 01.06.2009 15:44:54
dd/MM/yyyy HH:mm - 01.06.2009 15:44
dd[MM[yyyy HH^mm - 01[06[2009 15^44
dd\/MM\/yyyy HH:mm - 01/06/2009 15:44
System.Globalization.DateTimeFormatInfo.CurrentInfo.DateSeparator - .

Спрашивается чем слеш(/) неугодил?

четверг, 14 мая 2009 г.

Сваял утилитку "Tfs BatchUndo"

Время от времени подваливают программеры с просьбой сделать откат CheckOut для файликов. Все бы хорошо, но Checkout они делали до переустановки операционки, или смены компа или имени. До того как меня достало я писал скрипт для этого, а теперь все это можно сделать с помощью утилитки TFS BatchUndo.

Интересная статья на данную тему Undoing a checkout that belongs to another user.

четверг, 30 апреля 2009 г.

WiMAX таки в Уфе

Компания Yota объявила о начале тестовых испытаний своей сети в Уфе.
И с 1 мая начнет собирать заявки от желающих, из всей толпы будут отобраны 500 чемпионов-тестеров ;-)

Компания Yota, ведущий российский разработчик и поставщик мобильных сервисов на основе технологии 4-го поколения Mobile WiMAX, объявляет о начале опытной эксплуатации своей сети в Уфе. Для демонстрации и тестирования возможностей сети Mobile WiMAX в Уфе стартует программа Команда Yota.

Пятьсот жителей Уфы войдут в Команду Yota и станут первыми пользователями сети беспроводного быстрого доступа в интернет по технологии Mobile WiMAX — Yota Чемпионами. Во время действия программы, до середины лета 2009 года, Yota Чемпионам будет предоставлена возможность безлимитного использования всех возможностей сети. ....


Условия участия в программе «Команда Yota»
программа "Команда Yota"

среда, 22 апреля 2009 г.

SRM 438

Решаю потихонку задачки...

250
namespace SRM438
{
  public class UnluckyNumbers
  {
    public int getCount(int[] luckySet, int n)
    {
      Array.Sort(luckySet);

      int result = 0;

      for (int i = 0; i < luckySet.Length - 1; i++)
      {
        if (luckySet[i] < n & luckySet[i + 1] > n)
        {
          if (luckySet[i + 1] - 1 - luckySet[i] + 1 > 1)
          {
            result += (luckySet[i + 1] - n) * (n - luckySet[i]) - 1;
          }
        }
      }

      return result;
    }
  }
}


* This source code was highlighted with Source Code Highlighter.



Заюзал NUnit v2.5 для тестирования ;-)
[TestFixture]
  public class UnluckyNumbersTests
  {
    [TestCase(new int[] { 1, 7, 14, 10 }, 2,4)]
    [TestCase(new int[] { 4, 8, 13, 24, 30 }, 10,5)]
    [TestCase(new int[] { 10, 20, 30, 40, 50 }, 30,0)]
    [TestCase(new int[] { 3, 7, 12, 18, 25, 100, 33, 1000 }, 59,1065)]
    public void getCountTest(int[] luckySet, int n, int expectedResult)
    {
      UnluckyNumbers unluckyNumbers = new UnluckyNumbers();

      int result = unluckyNumbers.getCount(luckySet, n);

      Assert.AreEqual(expectedResult, result);
    }
  }


* This source code was highlighted with Source Code Highlighter.

SRM 438

Решаю потихонку задачки...

250
namespace SRM438
{
  public class UnluckyNumbers
  {
    public int getCount(int[] luckySet, int n)
    {
      Array.Sort(luckySet);

      int result = 0;

      for (int i = 0; i < luckySet.Length - 1; i++)
      {
        if (luckySet[i] < n & luckySet[i + 1] > n)
        {
          if (luckySet[i + 1] - 1 - luckySet[i] + 1 > 1)
          {
            result += (luckySet[i + 1] - n) * (n - luckySet[i]) - 1;
          }
        }
      }

      return result;
    }
  }
}


* This source code was highlighted with Source Code Highlighter.



Заюзал NUnit v2.5 для тестирования ;-)
[TestFixture]
  public class UnluckyNumbersTests
  {
    [TestCase(new int[] { 1, 7, 14, 10 }, 2,4)]
    [TestCase(new int[] { 4, 8, 13, 24, 30 }, 10,5)]
    [TestCase(new int[] { 10, 20, 30, 40, 50 }, 30,0)]
    [TestCase(new int[] { 3, 7, 12, 18, 25, 100, 33, 1000 }, 59,1065)]
    public void getCountTest(int[] luckySet, int n, int expectedResult)
    {
      UnluckyNumbers unluckyNumbers = new UnluckyNumbers();

      int result = unluckyNumbers.getCount(luckySet, n);

      Assert.AreEqual(expectedResult, result);
    }
  }


* This source code was highlighted with Source Code Highlighter.

среда, 25 марта 2009 г.

Top 100 Best Software Engineering Books

Подкинули ссылку на интересный кнол. Jurgen Appelo собрал топ 100 книг по теме "Software Engineering" или по русски "Разработка программного обеспечения". Для составления списка использовался Amazon.Для интересующихся приведены критерии отбора и технология подсчета рейтинга в конце кнола. Интересной особенностью списка является максимальная нейтральность по отношению к конкретным технологиям: Java, .NET, Ruby и PHP.

Самообразованию нет предела!

PS. читая Майкла Физерса прояснил некоторые вещи касаемо unit тестирования, которые ранее не мог понять.
PSS. стал больше времени уделять чтению технической литературы, полезно ;-)

quarkus за ссылку respect 8-)

четверг, 19 февраля 2009 г.

Денис Войханский - Социальные аспекты разработки

Очень интересная статья на тему управление проектами. Автор Денис Войханский.
В статье автор очень ясно изложил не только методы управления, а также типовые ошибки управления командой разработчиков.

Ключевые мысли:
Нацеливание команды на успех
Закон Листера
Закон Паркинсона
Good ожидания от человека
Больше доверия
Хорошие условия работы
Команда равных
Самоуправляемые команды
Daily Meetings
Iterations

UPD.
И в догонку - Социальные аспекты руководства, или как же всё таки «пинать» сотрудников. 2 года спустя.

четверг, 29 января 2009 г.

Как сделать скриншот программы?

How to take ScreenShot in C# or Visual Basic?

C#
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

private string TakeScreenShotFileName()
    {
      string screenshot = null;

      if (Application.OpenForms.Count > 0)
      {
        Bitmap bmp;
        Graphics gr;
        Rectangle bounds = Application.OpenForms[0].Bounds;

        screenshot = System.IO.Path.GetTempFileName();

        bmp = new Bitmap(bounds.Width, bounds.Height);

        gr = Graphics.FromImage(bmp);
        gr.CopyFromScreen(Application.OpenForms[0].Location, Point.Empty, bounds.Size);

        bmp.Save(screenshot, ImageFormat.Jpeg);
      }

      return screenshot ?? "";
    }


* This source code was highlighted with Source Code Highlighter.


VB
Imports System.Drawing
    Private Function TakeScreenshotFileName() As String
      Dim bounds As Rectangle = My.Application.MainForm.Bounds
      Dim fileNAme As String = Nothing

      Using b As New Bitmap(bounds.Width, bounds.Height)
        Using g = Graphics.FromImage(b)
          g.CopyFromScreen(My.Application.MainForm.Location, Point.Empty, bounds.Size)
        End Using
        fileNAme = System.IO.Path.GetTempFileName()
        b.Save(fileNAme, Imaging.ImageFormat.Jpeg)
      End Using
      Return fileName
    End Function


* This source code was highlighted with Source Code Highlighter.