10.24.2009

asp.net, website, objectdatasource

В asp.net есть такой тип проекта WebSite. Он отличается от WebApplication тем, что проектный сайт не создается, любой попавшый в папку файл добавляется в сайт, и самое главное - сайт не собирается в отдельную сборку. На продакшн сайт можно добавлять новые странички не компилируя их (ну есть конечно же предкомпиляция сайта, но см. далее). Каждая страничка компилируется через iis сервер в собственную сборку с рандомным именем. Как это разруливает сервер - загадка.

Для простой логики где все находится в пределах одной страницы все окей, а вот когда требуется вызвать код находящийся на другой страничке - начинаются проблемы: одна страничка ничего не знает о другой (т.к. находится в собственной сборке). Обычное решение - выносить такой нужный код в отдельную собственную сборку, типа библиотеки, закинуть ее в bin директорию сайта, подключать ее в страничках сайта и использовать в коде. Хорошо то оно хорошо. А что делать если ну никак не хочется выносить одну единственную функцию в библиотеку, код которой нужен только на одной единственной страничке?

Пример - нужно реализовать bind грида через object data source, и не через что-либо иное (такое может понадобится для использования фишек грида типа редактирования, удаления в табличке, сортировки, пейджинга и т.п.). Проблема сводится к тому что в SelectMethod нужно написать имя метода, в SelectParameters - параметры, а в TypeName - полное название типа где находится метод. А класс лежит в своей собственной сборке, а имя генерируется рандомно. Единственное решение проблемы - динамически заполнять поле TypeName на этапе загрузки страницы. Вот финальный код:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="myprojectclass.aspx.cs" Inherits="myprojectclass" %>

<asp:GridView ID="gridView1" runat="server" DataSourceID="objectDataSource1" AutoGenerateColumns="True" />
<asp:ObjectDataSource ID="objectDataSource1" runat="server" SelectMethod="GetData" TypeName="" ></asp:ObjectDataSource>

public partial class myprojectclass : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
         // ...
         objectDataSource1.TypeName = String.Format("{0}, {1}", this.GetType().FullName, this.GetType().Assembly);
         gridView1.DataBind();
    }
    
    public System.Collections.Generic.List<DataItem> GetData() {
         // ...
    }
}

Повторюсь - это будет работать в пределах одной страницы, код другой странички получить не получится. Только через собственную сборку. Выводы: 1. никогда не использовать WebSite 2. использовать только WebApplication - так как все получается логично и понятно 3. По возможности никогда не использовать ASP.NET - есть другие более удобные инструментарии веб-разработки

10.18.2009

Подсветка синтаксиса в блоге

Прикрутил к блогу подсветку синтаксиса кода. Некоторое время я провел за поисковиком, все примеры были не очень и в основном старые. Нашел кое-что подходящее на heisencoder.net. В итоге и использовал эту компоненту syntaxhighlighter. Еще есть старый репозиторий на гугл-коде. Жалко что пример на том блоге устарел и почему-то у меня не заработал. Благо у автора компоненты очень подробная док-ция Компонента представляет собой набор javascript-ов и css шаблонов, заходим на http://alexgorbatchev.com/pub/sh/ выбираем нужную версию и качаем. Можно и не качать, а использовать прямые ссылки на хостящиеся файлы. В общем внутри head-а странички вставляем следующий код:
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushXml.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCpp.js' type='text/javascript'/>

<script type='text/javascript'>
  SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';
                SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.defaults['gutter'] = true;
                SyntaxHighlighter.all();
</script>
Тем самым мы добавили нужные стили (у меня используется дефолтный, но вообще доступно несколько) и скрипты (здесь я добавил html, cpp, c#), настроили компоненту должным образом. За подробными комментариями по назначению, списку всех параметров и всех возможных скриптов - на сайт производителя. Потом в html-код сообщения добавляем
<pre class="brush: cpp; toolbar: true;">
 #include <iostream>
    int main() {
  std::cout << "hello" << std::endl;
 
 }
</pre>
P.S. Главное не забывать ескейпить символы...

10.15.2009

Индусы среди нас

Один человечек написал подобный код:
  class Item {
    public static void UpdateItem(Item _item) {
    // ...
    }
  }

  Item it;
  // ...
  Item.UpdateItem(it);
Попахивает безграммотностью. Не логично использовать статический метод который принимает экземпляр собственного класса. Я попросил человечка избавиться от статического метода. Код был переписан вот в это:
  class Item {
    public void UpdateItem(Item _item) {
    // ...
    }
  }
  
  Item it;
  // ...
  new Item().UpdateItem(it);
Да, оказывается у некоторых в крови индусские гены и они в тайне по ночам молятся шестируким богам. И почему нельзя сделать вот так, по простому:
  class Item {
    public void UpdateItem() {
    // ...
    }
  } 

  Item it;
  // ...
  it.UpdateItem();