16.06.2014

asp:LinkButton Visible

Из-за бага иногда не удаётся спрятать программно asp:LinkButton через свойство Visible. Можно спрятать через добавление стиля 'display: none'.

    this.LinkButton.Style.Add("display", "none");

14.04.2010

Object Initializers в C# 3.0 или как не писать много конструкторов

В C# 3.0 появилась замечательная вещь - инициализаторы объектов (Object Initializers). Это, в принципе, syntactic sugar, и реально позволяет создавать объекты "короче", а значит, код становится простым и читаемым.

Рассмотрим, как раньше мы создавали объект:
class Contact
{
    public string Name { get; set; }
    public int YearofBirth { get; set; }
}

Contact c1 = new Contact();
c1.Name = "John";
c1.YearofBirth = 1980;

Если мы напишем для класса конструктор с двумя параметрами, то инициализация станет короче:
Contact c1 = new Contact("John", 1980);

Минус очевиден - для каждого набора параметров надо писать свой конструктор (значения по умолчанию для параметров появились лишь в C# 4.0). Но теперь нам доступен другой способ инициализации:
Contact c1 = new Contact { Name = "John", YearofBirth = 1980 };

Присваивания свойств идут через запятую в фигурных скобках, внутри скобок ";" не ставится.

Предположим, что конструктор обязательно должен принимать Name. Тогда можно инициализировать объект следующим образом:
Contact c1 = new Contact("Wei-Meng Lee") { YearofBirth=1980 };

Теперь мы имеем эффективное средство для инициализации свойств для ленивых, т.е. для нас, программистов.

Похожим образом теперь можно создавать коллекции - это называется Collection Initializers:

раньше
List Contacts = new List ();
Contacts.Add(new Contact { Name = "John", YearofBirth = 1980 });
Contacts.Add(new Contact { Name = "Mary", YearofBirth = 1986 });
Contacts.Add(new Contact { Name = "Richard",YearofBirth=1948 });

теперь
List Contacts = new List() {
    new Contact { Name = "John", YearofBirth = 1980 },
    new Contact { Name = "Mary", YearofBirth = 1986 },
    new Contact { Name = "Richard", YearofBirth = 1948 }
};

10.04.2010

Тестовый smtp-сервер с помощью python

Оказывается, Питон прямо "из коробки" умеет делать fake stmp server, никуда ничего не отправляющий, а логирующий все в stdout (в консоль, да). Все, что для этого надо - поставить python и набрать в командной строке

python -m smtpd -n -c DebuggingServer localhost:25

Порт, конечно же, можно менять. В результате все отправляемые в этот порт письма будут выводиться в консоли вместе со всеми заголовками.

Если кто не понял, зачем это надо: есть задача проверить рассылку писем на много адресов, а спамить никого не охота, да и самому заводить много ящиков лень. Вот тогда вы берете Python и запускаете отладочный smtp-сервер. Пишите письма на здоровье!

13.11.2009

Re-использование кода

Елена Сагалаева интересную заметку написала. Похоже, что у всех такие проблемы возникают и идеально не решаются. У нас гораздо меньше, чем 50 человек, но какая-то дисциплина тоже требуется. И решил я, что:

1. Нужен корпоративный портал, который предоставит всю функциональность в удобном виде (что-то типа code.google.com, sourceforge и т.п.)
2. Все модули, которые предполагается повторно использовать, должны версионироваться - если в каком-то проекте уже используется какая-то версия модуля, то его нельзя менять!
3. Модуль должен быть снабжен документацией в вики-формате, состоящей из двух частей - человеческой и автосгенерированной по коду.
4. Документация должна версионироваться вместе с модулем.
5. При создании новой версии модуля необходимо обязательно указывать отличия. Провели рефакторинг, ускорили алгоритм на 20% - будьте добры написать. Возможно, кто-то только этого и ждал.
6. Разработчики проекта, в котом используется такой общий модуль, автоматически подписываются (пожизненно :) на выход новых версий модуля.
7. Модули должны быть доступны как в собранном виде, так и в виде исходников, чтобы все-таки позволить сделать копи-паст.
8. И было бы неплохо иметь утилиту, которая попробует собрать все (!) проекты, использующие данный модуль, с новой версией модуля. И запустит тесты. Ибо удобство превыше всего.

Ну и должна быть страница, которая угадывает мысли. Нужен вам какой-то функционал - пожалуйста, смотрите вот этот модуль. Без этой страницы никакое повторное использование невозможно. Именно у нее будут спрашивать: "а не написал ли уже кто-нибудь то, что мне нужно?"

28.10.2009

Как определить город посетителя (определение адреса по ip)

Все хорошие сайты умеют определять адрес, вернее, город, в котором живет посетитель. И делается это, понятно, по ip-адресу. Только вот кто откуда берет географические привязки ip? Лично я решил использовать сервис IpGeoBase. Он позволяет скачать базу целиком или же использовать xml-сервис. Я предпочел пока второй вариант, чтобы не заморачиваться с ежедневным выкачиванием базы. Понятно, что когда поток посетителей у меня возрастет до небывалых высот, я буду выкачивать базу. А пока у меня это работает очень быстро и выглядит так (код на Питоне 2.6):

#coding=utf-8

def getGeoData(ip):
  """Получить город по ip-адресу (адрес предается как строка).
  Возвращает словарь с элементами-строками city, region, district
  "
""

  import httplib
  import re
  from xml.dom.minidom import parseString

  conn = httplib.HTTPConnection("194.85.91.253:8090")
  conn.request("POST", "/geo/geo.html", \
    "<ipquery><fields><all/></fields><ip-list><ip>" + ip + \
    "</ip></ip-list></ipquery>")
  resp = conn.getresponse()

  data = resp.read()
  conn.close()

  # если ничего не найдено
  if re.search("<message>Not found</message>", data):
    return None

  dom = parseString(data)
  city = dom.documentElement.getElementsByTagName('city')[0]\
    .firstChild.nodeValue
  region = dom.documentElement.getElementsByTagName('region')[0]\
    .firstChild.nodeValue
  district = dom.documentElement.getElementsByTagName('district')[0]\
    .firstChild.nodeValue

  return {'city' : city, 'region' : region, 'district' : district}


Теперь вопрос остальным: кто как справляется с этой задачей?

UPD: иногда сервис неверно определяет адрес по ip, потому что некоторые провайдеры используют общий DHCP для всех регионов, или же информация об адресах еще не собрана. Войдя на IpGeoBase, можно указать свой правильный адрес, если по ip он определился неверно.