<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/"><channel><title>ASP.NET</title><link>http://spass.name/category/5.aspx</link><description>ASP.NET</description><language>ru-RU</language><copyright>Anton Spass</copyright><managingEditor>anton@spass.name</managingEditor><generator>Subtext Version 1.4.1.0</generator><image><title>Inter nos</title><url>http://spass.name/RSS2Image.gif</url><link>http://spass.name/Default.aspx</link><width>77</width><height>60</height><description /></image><item><title>XPath Query generates Unknown method exception (MSXML)</title><link>http://spass.name/archive/2005/11/08/763.aspx</link><description>&lt;P&gt;Обратная совместимость в очередной раз становится причиной конфуза. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;Если вы, как и я, пытаетесь с помощью упомянутого MSXML DOM сделать выборку из&amp;nbsp;xml-документа и недоумеваете, почему при вызове &lt;EM&gt;стандартных&lt;/EM&gt; XPath-методов на клиете вылетает Unknown method exception, рекомендую просмотреть &lt;A href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;q288913"&gt;эту&lt;/A&gt; статью в Microsoft KB. Оказывается, дефолтовым&amp;nbsp;языком в MSXML является XSLPattern, а не XPath. Потому перед вызовами XPath-методов необходимо явно указать SelectionLanguage:&lt;/P&gt;
&lt;BR&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt; 
myDomDoc.setProperty("SelectionLanguage", "XPath"); 
&lt;/span&gt;&lt;/pre&gt; 
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://spass.name/aggbug/763.aspx" width="1" height="1" /&gt;</description><author>anton.spass@offshorecreations.com</author><guid>http://spass.name/archive/2005/11/08/763.aspx</guid><pubDate>Tue, 08 Nov 2005 20:14:00 GMT</pubDate><wfw:comment>http://spass.name/comments/763.aspx</wfw:comment><comments>http://spass.name/archive/2005/11/08/763.aspx#feedback</comments><wfw:commentRss>http://spass.name/comments/commentRss/763.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/763.aspx</trackback:ping></item><item><title>Reflection in Javascript</title><link>http://spass.name/archive/2005/03/22/209.aspx</link><description>&lt;P&gt;Как выяснилось, получить список свойств объекта можно и в Javascript. Пример ниже наглядно демонстрирует это. Прием возвращает не только свойства, но и события объекта.&lt;/P&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;SCRIPT&lt;/span&gt; &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;language&lt;/span&gt;&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;="javascript"&lt;/span&gt;&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;gt;&lt;/span&gt;
function GetProperties()
{
  var properties = "";
  for(var property in document) properties += property + "&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;br&lt;/span&gt;&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;gt;&lt;/span&gt;";
  document.write(properties)
}
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: Maroon; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;SCRIPT&lt;/span&gt;&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;img src="http://spass.name/aggbug/209.aspx" width="1" height="1" /&gt;</description><author>anton.spass@offshorecreations.com</author><guid>http://spass.name/archive/2005/03/22/209.aspx</guid><pubDate>Tue, 22 Mar 2005 09:55:00 GMT</pubDate><wfw:comment>http://spass.name/comments/209.aspx</wfw:comment><comments>http://spass.name/archive/2005/03/22/209.aspx#feedback</comments><wfw:commentRss>http://spass.name/comments/commentRss/209.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/209.aspx</trackback:ping></item><item><title>CMS: Использование формата .mht</title><link>http://spass.name/archive/2004/11/28/167.aspx</link><description>
		&lt;p&gt;
				&lt;u&gt;Формат MHT&lt;/u&gt;
		&lt;/p&gt;
		&lt;p&gt;Существует множество возможных вариантов построения системы управления контентом, и многие из них неплохо описаны. &lt;/p&gt;
		&lt;p&gt;Сегодня хотелось бы подробнее остановиться на использовании MHT формата для хранения контента. Для начала упомяну, что формат MHT основан на MIME кодировании и позволяет держать в одном файле текстовый и графический контент страницы. Подробнее о формате &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_mime_encapsulation_of_aggregate_html_documents_mhtml_.asp"&gt;здесь&lt;/a&gt;. Начиная с версии 5.5, сохранение страниц в MHT поддерживается Internet Explorer. Более того, приложения пакета MS Office (например, Word и Publisher) также позволяют работать с MHT файлами. Отсюда и удобства применения формата:&lt;/p&gt;
		&lt;ul&gt;
				&lt;li&gt;для конечных пользователей CMS - редактирование контента в любимом редакторе, что позволяет ориентироваться на пользователей с любым уровнем подготовки/знания HTML. 
&lt;/li&gt;
				&lt;li&gt;для разработчиков: простота server-side работы с контентом. Страницы контента хранятся и обрабатываются как единая сущность, вне зависимости от наличия в них вложенных элементов (графики, анимации etc)&lt;/li&gt;
		&lt;/ul&gt;
		&lt;p&gt;Главный минус формата - контент в MIME весит примерно на 33% больше, чем страница, сохраненная в html + вложения. Однако это ограничение можно обойти, воспользовавшись GZIP кодированием вложенных элементов страницы перед сохранением их в MIME.&lt;/p&gt;
		&lt;p&gt;Теперь немного о тонкостях работы с форматом на примере.&lt;/p&gt;
		&lt;p&gt;
				&lt;u&gt;Задача&lt;/u&gt;
		&lt;/p&gt;
		&lt;p&gt;Предположим, наша CMS хранит файлы контента в базе и выводит страницы контента конечному пользователю напрямую из базы. То есть в Response мы записываем те самые mht файлы.&lt;/p&gt;
		&lt;p&gt;Кроме того, будем исходить из допущения, что mht файлы должны выводиться браузером напрямую,&lt;br /&gt;без предварительной отгрузки контента в кеш браузера и последующего локального открытия файла.&lt;br /&gt;Это позволит обеспечить прозрачныю работу с контентом для конечных пользователей, так, будто&lt;br /&gt;они работают с простым html контентом.&lt;/p&gt;
		&lt;p&gt;
				&lt;u&gt;Решение&lt;/u&gt;
		&lt;/p&gt;
		&lt;p&gt;Как обычно, есть два варианта проделать запись файла в Response:&lt;/p&gt;
		&lt;ol&gt;
				&lt;li&gt;создать пустую aspx страницу, codebehind-класс которой будет подбирать информацию о запрошенном контенте из Query String и выводить соответствующий файл в респонс; 
&lt;/li&gt;
				&lt;li&gt;создать handler, проделывающий то же самое.&lt;/li&gt;
		&lt;/ol&gt;
		&lt;p&gt;В этом месте необходимо оговориться, что security особенности IE не позволяют:&lt;/p&gt;
		&lt;ul&gt;
				&lt;li&gt;открыть в браузере MHT-файл с расшинением, отличным от .mht (.mhtml), даже если на сервере &lt;br /&gt;правильно указан content-type; 
&lt;/li&gt;
				&lt;li&gt;открыть mht-файл в случае, если в реквесте присутствует query string. То есть, следующий URL  &lt;br /&gt;вернет нам 404, даже если указанный в нем файл действительно присутствует на сервере:&lt;/li&gt;
		&lt;/ul&gt;
		&lt;pre&gt;http://localhost/MyApp/Page.mht?id=1&lt;/pre&gt;
		&lt;br /&gt;
		&lt;p&gt;Последнее обстоятельство может вызвать конфуз у разработчика. Причина подобного ограничения функциональности IE, как всегда, &lt;a href="http://www3.ca.com/securityadvisor/vulninfo/vuln.aspx?id=26699"&gt;vulnerability issue&lt;/a&gt;. &lt;/p&gt;
		&lt;p&gt;Вышеизложенные замечания указывают нам путь решения поставленной задачи:&lt;/p&gt;
		&lt;ol&gt;
				&lt;li&gt;зарегистрировать в настройках приложения (IIS) расширение .mht как обрабатываемое aspnet_isapi.dll. Важно! Необходимо выключить checkbox проверки существования файла. 
&lt;/li&gt;
				&lt;li&gt;создать в приложении хендлер для расширения .mht, который не требует query string для передачи на сервер информации о запрошенной странице.&lt;/li&gt;
		&lt;/ol&gt;
		&lt;p&gt;Для реализации второго пункта как вариант можно передавать параметры прямо в имени запрошенной страницы. То есть, URL будет выглядеть примерно так:&lt;/p&gt;
		&lt;pre&gt;http://localhost/MyApp/ViewContentCategory10Type1.mht&lt;/pre&gt;
		&lt;br /&gt;
		&lt;p&gt;Параметры из URL запрошенного файла подберем с помощью Regex, вот маленький пример:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;
HttpRequest Request &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; context.Request;
  HttpResponse Response &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; context.Response;
  &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;int&lt;/span&gt; categoryId &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; -1;
  &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;int&lt;/span&gt; type &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; -1;
  &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;try&lt;/span&gt;
  {
   Match match &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Regex.Match(Request.Path, 
&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;@"(ViewContentCategory)(\d+)(Type)(\d+)"&lt;/span&gt;,
RegexOptions.IgnoreCase);
   &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;if&lt;/span&gt; (match !&lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;null&lt;/span&gt;)
   {
    categoryId &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Convert.ToInt32(match.Groups[2].Value);
    type &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Convert.ToInt32(match.Groups[4].Value);
   }
  }
  &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;catch&lt;/span&gt;
  {}

&lt;/span&gt;&lt;/pre&gt; &lt;br /&gt;&lt;p&gt;После получения из базы byte[] с нужным файлом остается только правильно прописать его в Response: &lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt; 
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; WriteContentToResponse(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;byte&lt;/span&gt;[] content, 
HttpResponse Response)
  {  
   Response.BufferOutput &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;true&lt;/span&gt;;
   Response.Clear();
   Response.ContentType=&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"message/rfc822"&lt;/span&gt;;
   
   Response.BinaryWrite(content);
   Response.End();
  }

 &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;img src="http://spass.name/aggbug/167.aspx" width="1" height="1" /&gt;</description><author>anton@spass.name</author><guid>http://spass.name/archive/2004/11/28/167.aspx</guid><pubDate>Sun, 28 Nov 2004 22:35:00 GMT</pubDate><wfw:comment>http://spass.name/comments/167.aspx</wfw:comment><comments>http://spass.name/archive/2004/11/28/167.aspx#feedback</comments><slash:comments>32</slash:comments><wfw:commentRss>http://spass.name/comments/commentRss/167.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/167.aspx</trackback:ping><body xmlns="http://www.w3.org/1999/xhtml">
		<p>
				<u>Формат MHT</u>
		</p>
		<p>Существует множество возможных вариантов построения системы управления контентом, и многие из них неплохо описаны. </p>
		<p>Сегодня хотелось бы подробнее остановиться на использовании MHT формата для хранения контента. Для начала упомяну, что формат MHT основан на MIME кодировании и позволяет держать в одном файле текстовый и графический контент страницы. Подробнее о формате <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_mime_encapsulation_of_aggregate_html_documents_mhtml_.asp">здесь</a>. Начиная с версии 5.5, сохранение страниц в MHT поддерживается Internet Explorer. Более того, приложения пакета MS Office (например, Word и Publisher) также позволяют работать с MHT файлами. Отсюда и удобства применения формата:</p>
		<ul>
				<li>для конечных пользователей CMS - редактирование контента в любимом редакторе, что позволяет ориентироваться на пользователей с любым уровнем подготовки/знания HTML. 
</li>
				<li>для разработчиков: простота server-side работы с контентом. Страницы контента хранятся и обрабатываются как единая сущность, вне зависимости от наличия в них вложенных элементов (графики, анимации etc)</li>
		</ul>
		<p>Главный минус формата - контент в MIME весит примерно на 33% больше, чем страница, сохраненная в html + вложения. Однако это ограничение можно обойти, воспользовавшись GZIP кодированием вложенных элементов страницы перед сохранением их в MIME.</p>
		<p>Теперь немного о тонкостях работы с форматом на примере.</p>
		<p>
				<u>Задача</u>
		</p>
		<p>Предположим, наша CMS хранит файлы контента в базе и выводит страницы контента конечному пользователю напрямую из базы. То есть в Response мы записываем те самые mht файлы.</p>
		<p>Кроме того, будем исходить из допущения, что mht файлы должны выводиться браузером напрямую,<br />без предварительной отгрузки контента в кеш браузера и последующего локального открытия файла.<br />Это позволит обеспечить прозрачныю работу с контентом для конечных пользователей, так, будто<br />они работают с простым html контентом.</p>
		<p>
				<u>Решение</u>
		</p>
		<p>Как обычно, есть два варианта проделать запись файла в Response:</p>
		<ol>
				<li>создать пустую aspx страницу, codebehind-класс которой будет подбирать информацию о запрошенном контенте из Query String и выводить соответствующий файл в респонс; 
</li>
				<li>создать handler, проделывающий то же самое.</li>
		</ol>
		<p>В этом месте необходимо оговориться, что security особенности IE не позволяют:</p>
		<ul>
				<li>открыть в браузере MHT-файл с расшинением, отличным от .mht (.mhtml), даже если на сервере <br />правильно указан content-type; 
</li>
				<li>открыть mht-файл в случае, если в реквесте присутствует query string. То есть, следующий URL  <br />вернет нам 404, даже если указанный в нем файл действительно присутствует на сервере:</li>
		</ul>
		<pre>http://localhost/MyApp/Page.mht?id=1</pre>
		<br />
		<p>Последнее обстоятельство может вызвать конфуз у разработчика. Причина подобного ограничения функциональности IE, как всегда, <a href="http://www3.ca.com/securityadvisor/vulninfo/vuln.aspx?id=26699">vulnerability issue</a>. </p>
		<p>Вышеизложенные замечания указывают нам путь решения поставленной задачи:</p>
		<ol>
				<li>зарегистрировать в настройках приложения (IIS) расширение .mht как обрабатываемое aspnet_isapi.dll. Важно! Необходимо выключить checkbox проверки существования файла. 
</li>
				<li>создать в приложении хендлер для расширения .mht, который не требует query string для передачи на сервер информации о запрошенной странице.</li>
		</ol>
		<p>Для реализации второго пункта как вариант можно передавать параметры прямо в имени запрошенной страницы. То есть, URL будет выглядеть примерно так:</p>
		<pre>http://localhost/MyApp/ViewContentCategory10Type1.mht</pre>
		<br />
		<p>Параметры из URL запрошенного файла подберем с помощью Regex, вот маленький пример:</p>
<pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">
HttpRequest Request <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> context.Request;
  HttpResponse Response <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> context.Response;
  <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">int</span> categoryId <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> -1;
  <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">int</span> type <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> -1;
  <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">try</span>
  {
   Match match <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Regex.Match(Request.Path, 
<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">@"(ViewContentCategory)(\d+)(Type)(\d+)"</span>,
RegexOptions.IgnoreCase);
   <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">if</span> (match !<span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">null</span>)
   {
    categoryId <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Convert.ToInt32(match.Groups[2].Value);
    type <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Convert.ToInt32(match.Groups[4].Value);
   }
  }
  <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">catch</span>
  {}

</span></pre> <br /><p>После получения из базы byte[] с нужным файлом остается только правильно прописать его в Response: </p><br /><pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"> 
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> WriteContentToResponse(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">byte</span>[] content, 
HttpResponse Response)
  {  
   Response.BufferOutput <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">true</span>;
   Response.Clear();
   Response.ContentType=<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"message/rfc822"</span>;
   
   Response.BinaryWrite(content);
   Response.End();
  }

 </span></pre><br /><img src="http://spass.name/aggbug/167.aspx" width="1" height="1" /></body></item><item><title>Using Reflection to Bind Business Objects to ASP.NET Form Controls</title><link>http://spass.name/archive/2004/11/22/163.aspx</link><description>&lt;p&gt;Джон Даер (John Dyer) опубликовал замечательную &lt;a href="http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/aspformbinding.asp"&gt;статью&lt;/a&gt;, демонстрирующую, каким образом можно использовать библиотеку Reflection для унификации бинда бизнес-объектов к контролам веб-форм. Предложенный подход позволяет сократить объем необходимого для бинда кода за счет использования построенной на Reflection бинд-прослойки.&lt;/p&gt;&lt;p&gt;Замечу, однако, что в случае работы с бизнес-объектами, определенными в веб-сервисе, необходимо использовать вместо предложенной коллекции&amp;nbsp;PropertyInfo[] коллекцию FieldInfo[]. Этот неприятный момент объясняется тем обстоятельством, что инструмент WSDL сериализует Property как Field.&lt;/p&gt;&lt;p&gt;Вдвойне приятно было отметить, что предложенный подход перекликается с приведенным&amp;nbsp;в посте &lt;a href="http://spass.name/archive/2004/07/15/156.aspx"&gt;Reflection: Пример динамического возвращения поля custom-объекта сессии&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://spass.name/aggbug/163.aspx" width="1" height="1" /&gt;</description><author>anton.spass@offshorecreations.com</author><guid>http://spass.name/archive/2004/11/22/163.aspx</guid><pubDate>Mon, 22 Nov 2004 01:09:00 GMT</pubDate><wfw:comment>http://spass.name/comments/163.aspx</wfw:comment><comments>http://spass.name/archive/2004/11/22/163.aspx#feedback</comments><wfw:commentRss>http://spass.name/comments/commentRss/163.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/163.aspx</trackback:ping></item><item><title>StringCollectionEditor</title><link>http://spass.name/archive/2004/11/04/160.aspx</link><description>&lt;p&gt;Стефен Тауб (Stephen Toub),&amp;nbsp;научный редактор журнала &lt;a href="http://msdn.microsoft.com/msdnmag/"&gt;MSDN Magazine&lt;/a&gt;, в ответ на мой &lt;a href="http://blogs.msdn.com/toub/archive/2004/09/23/233607.aspx#241181"&gt;вопрос&lt;/a&gt; раскрывает&amp;nbsp;особенности использования StringCollectionEditor:&lt;/p&gt;&lt;p&gt;&lt;a href="http://blogs.msdn.com/toub/archive/2004/10/12/241277.aspx"&gt;http://blogs.msdn.com/toub/archive/2004/10/12/241277.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Исчерпывающе.&lt;/p&gt;&lt;img src="http://spass.name/aggbug/160.aspx" width="1" height="1" /&gt;</description><author>anton.spass@offshorecreations.com</author><guid>http://spass.name/archive/2004/11/04/160.aspx</guid><pubDate>Thu, 04 Nov 2004 20:41:00 GMT</pubDate><wfw:comment>http://spass.name/comments/160.aspx</wfw:comment><comments>http://spass.name/archive/2004/11/04/160.aspx#feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://spass.name/comments/commentRss/160.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/160.aspx</trackback:ping></item><item><title>AppDomain: Unlocking files used by Application</title><link>http://spass.name/archive/2004/10/09/158.aspx</link><description>
		&lt;p&gt;
				&lt;u&gt;Проблема &lt;/u&gt;
		&lt;/p&gt;
		&lt;p&gt;Сборки, подгружаемые .NET приложением (автоматически или принудительно) блокируются процессом, в котором работает AppDomain приложения. В некоторых случаях небходимо, чтобы используемые процессом сборки оставались открытыми для записи (например, в ситуации постоянного обновления сборки). &lt;/p&gt;
		&lt;p&gt;
				&lt;u&gt;Решение &lt;/u&gt;
		&lt;/p&gt;
		&lt;p&gt;.NET framework позволяет решить поставленную задачу путем принудительного включения механизма ShadowCopy при обращении к файлам. Таким образом, вместо оригинального файла в AppDomain будет использована его shadow copy, и оригинальный файл не блокируется доменом приложения. Флаг на использование shadow copy выставляется методом AppDomain.SetShadowCopyFiles() &lt;/p&gt;
		&lt;p&gt;
				&lt;u&gt;Пример &lt;/u&gt;
		&lt;/p&gt;
		&lt;p&gt;В приведенном ниже примере сборка sl.dll останется незаблокированной. &lt;/p&gt;&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt; 
Thread.GetDomain().SetShadowCopyFiles(); 
Assembly asm &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; 
Assembly.LoadFrom(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;@"D:\Projects\SL\bin\Debug\sl.dll"&lt;/span&gt;); 
&lt;/span&gt;&lt;/pre&gt;&lt;img src="http://spass.name/aggbug/158.aspx" width="1" height="1" /&gt;</description><author>anton@spass.name</author><guid>http://spass.name/archive/2004/10/09/158.aspx</guid><pubDate>Sat, 09 Oct 2004 02:02:00 GMT</pubDate><wfw:comment>http://spass.name/comments/158.aspx</wfw:comment><comments>http://spass.name/archive/2004/10/09/158.aspx#feedback</comments><wfw:commentRss>http://spass.name/comments/commentRss/158.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/158.aspx</trackback:ping><body xmlns="http://www.w3.org/1999/xhtml">
		<p>
				<u>Проблема </u>
		</p>
		<p>Сборки, подгружаемые .NET приложением (автоматически или принудительно) блокируются процессом, в котором работает AppDomain приложения. В некоторых случаях небходимо, чтобы используемые процессом сборки оставались открытыми для записи (например, в ситуации постоянного обновления сборки). </p>
		<p>
				<u>Решение </u>
		</p>
		<p>.NET framework позволяет решить поставленную задачу путем принудительного включения механизма ShadowCopy при обращении к файлам. Таким образом, вместо оригинального файла в AppDomain будет использована его shadow copy, и оригинальный файл не блокируется доменом приложения. Флаг на использование shadow copy выставляется методом AppDomain.SetShadowCopyFiles() </p>
		<p>
				<u>Пример </u>
		</p>
		<p>В приведенном ниже примере сборка sl.dll останется незаблокированной. </p><pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"> 
Thread.GetDomain().SetShadowCopyFiles(); 
Assembly asm <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> 
Assembly.LoadFrom(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">@"D:\Projects\SL\bin\Debug\sl.dll"</span>); 
</span></pre><img src="http://spass.name/aggbug/158.aspx" width="1" height="1" /></body></item><item><title>Reflection: Пример динамического возвращения поля custom-объекта сессии</title><link>http://spass.name/archive/2004/07/15/156.aspx</link><description>
		&lt;p&gt;В случае, если мы хотим обратиться к полю объекта сессии, и нам заранее неизвестен тип объекта, причем интерфейсное обращение также невозможно, на помощь придет библиотека Reflection. &lt;/p&gt;
		&lt;p&gt;В приведенном ниже примере метод GetDataSetFromSessionObject() вернет нам значение DataSet-поля объекта сессии, получая сведения о типе объекта, имени поля и собственно имени объекта динамически в runtime через QueryString: &lt;/p&gt;&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;string&lt;/span&gt; objectType;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;string&lt;/span&gt; objectName;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;string&lt;/span&gt; fieldName;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; FieldInfo fi;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; Type type;
...
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; DataSet GetDataSetFromSessionObject()
{
 objectType &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Request[&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"objectType"&lt;/span&gt;].ToString();
 objectName &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Request[&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"objectName"&lt;/span&gt;].ToString();
 fieldName &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Request[&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"fieldName"&lt;/span&gt;].ToString();
 &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;object&lt;/span&gt; sessionObject &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Session[objectName];
 type &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; System.Type.GetType(objectType);    
 fi &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; type.GetField(fieldName);
 &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;return&lt;/span&gt; 
(DataSet)fi.GetValue((Convert.ChangeType(sessionObject, type)));
}
&lt;/span&gt;&lt;/pre&gt;&lt;img src="http://spass.name/aggbug/156.aspx" width="1" height="1" /&gt;</description><author>anton@spass.name</author><guid>http://spass.name/archive/2004/07/15/156.aspx</guid><pubDate>Thu, 15 Jul 2004 04:44:00 GMT</pubDate><wfw:comment>http://spass.name/comments/156.aspx</wfw:comment><comments>http://spass.name/archive/2004/07/15/156.aspx#feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://spass.name/comments/commentRss/156.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/156.aspx</trackback:ping><body xmlns="http://www.w3.org/1999/xhtml">
		<p>В случае, если мы хотим обратиться к полю объекта сессии, и нам заранее неизвестен тип объекта, причем интерфейсное обращение также невозможно, на помощь придет библиотека Reflection. </p>
		<p>В приведенном ниже примере метод GetDataSetFromSessionObject() вернет нам значение DataSet-поля объекта сессии, получая сведения о типе объекта, имени поля и собственно имени объекта динамически в runtime через QueryString: </p><pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> objectType;
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> objectName;
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> fieldName;
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> FieldInfo fi;
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> Type type;
...
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> DataSet GetDataSetFromSessionObject()
{
 objectType <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Request[<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"objectType"</span>].ToString();
 objectName <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Request[<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"objectName"</span>].ToString();
 fieldName <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Request[<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"fieldName"</span>].ToString();
 <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">object</span> sessionObject <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Session[objectName];
 type <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> System.Type.GetType(objectType);    
 fi <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> type.GetField(fieldName);
 <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">return</span> 
(DataSet)fi.GetValue((Convert.ChangeType(sessionObject, type)));
}
</span></pre><img src="http://spass.name/aggbug/156.aspx" width="1" height="1" /></body></item><item><title>Особенности PreRender для пользовательских контролов</title><link>http://spass.name/archive/2004/07/01/154.aspx</link><description>&lt;P&gt;Столкнулся с интересной ситуацией. Оказывается, если на первую отгрузку (!IsPostBack) пользовательского контрола выставить его свойство Visible в false, на последующих постбеках для контрола не будет сгенерировано событие PreRender. При этом событие PageLoad будет продолжать генериться. &lt;/P&gt;
&lt;P&gt;Например, в приведенном ниже фрагменте мы никогда не попадем в обработчик MyControl_PreRender на любую Postback-отгрузку родительской страницы:&lt;/P&gt;
&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;class&lt;/span&gt; MyControl : System.Web.UI.UserControl
{
    &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;private&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;object&lt;/span&gt; sender, System.EventArgs e)
    {
         &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;.Visible &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;false&lt;/span&gt;;
    }
    
    ...
    &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;private&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; InitializeComponent()
    {
         &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;.Load += &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; System.EventHandler(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;.Page_Load);
         &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;.PreRender += &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; EventHandler(MyControl_PreRender);
    }
    ...
    &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;private&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; MyControl_PreRender(objet sender, EventArgs e)
    {
        ...
    }
}
&lt;/span&gt;&lt;/pre&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;Резюмируем:&lt;/STRONG&gt; следует применять другие способы "прятать" содержимое пользовательского контрола, если в контроле требуется использовать событие PreRender.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://spass.name/aggbug/154.aspx" width="1" height="1" /&gt;</description><author>anton.spass@offshorecreations.com</author><guid>http://spass.name/archive/2004/07/01/154.aspx</guid><pubDate>Thu, 01 Jul 2004 05:27:00 GMT</pubDate><wfw:comment>http://spass.name/comments/154.aspx</wfw:comment><comments>http://spass.name/archive/2004/07/01/154.aspx#feedback</comments><wfw:commentRss>http://spass.name/comments/commentRss/154.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/154.aspx</trackback:ping></item><item><title>Starting..............[OK]</title><link>http://spass.name/archive/2004/06/25/150.aspx</link><description>&lt;P&gt;Блог стартовал, всем добро пожаловать :)&lt;/P&gt;
&lt;P&gt;Опубликована статья на тему TDD:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://spass.name/articles/149.aspx"&gt;Test-Driven Development in .Net&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Приветствуются любые замечания и фидбеки, равно как и сообщения о возможных неточностях.&lt;/P&gt;&lt;img src="http://spass.name/aggbug/150.aspx" width="1" height="1" /&gt;</description><author>anton.spass@offshorecreations.com</author><guid>http://spass.name/archive/2004/06/25/150.aspx</guid><pubDate>Fri, 25 Jun 2004 03:30:00 GMT</pubDate><wfw:comment>http://spass.name/comments/150.aspx</wfw:comment><comments>http://spass.name/archive/2004/06/25/150.aspx#feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://spass.name/comments/commentRss/150.aspx</wfw:commentRss><trackback:ping>http://spass.name/services/trackbacks/150.aspx</trackback:ping></item></channel></rss>