вторник, 17 апреля 2012 г.

Эмуляция "Прогресса выполнения" или как показать этот самый прогресс для полного ПостБека(Full PostBack) в АпдейтПанели(UpdatePanel)

Исходные данные.
У нас имеется АпдейтПанель(UpdatePanel). В этой АпдейтПанели у нас две кнопки. По нажатию на каждую кнопку приложение делает что-то. Также у нас имеется АпдейтПрогрес(UpdateProgress) для нашей панели. НО одна из кнопок генерирует полный ПостБек (PostBack).

<%@ Page Title="Home Page" Language="vb" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="UpdatePanelProgressEmulation._Default" %>
<%-- It is registration for a web user control that include presentation layout of our progress information. --%>
<%@ Register src="Preloader.ascx"  tagname="Preloader" tagprefix="uc1" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:ScriptManager ID="ScriptManagerMain" unat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanelMain" runat="server">
        <Triggers>
            <%--Register our full postback action for button--%>
            <asp:PostBackTrigger ControlID="btnWithPostBackTrigger" />
        </Triggers>
        <ContentTemplate>
            <%--UpdateProgress - uses ucPreloader. As in the above code.--%>
            <asp:UpdateProgress ID="UpdateProgressMain" EnableViewState="false"    AssociatedUpdatePanelID="UpdatePanelMain" runat="server">
                <ProgressTemplate>
                    <uc1:Preloader    ID="ucPreloader" ClientIDMode="Static"   runat="server" />
                </ProgressTemplate>
            </asp:UpdateProgress>
       
            <asp:Button runat="server" ID="btnWithoutPostBackTrigger" Text="Button without PostBackTrigger " BackColor="#006600" BorderStyle="Solid" BorderColor="#003300" ForeColor="White"/>
            <asp:Button runat="server" ID="btnWithPostBackTrigger" Text="Button with PostBackTrigger" BackColor="#CC0000" BorderStyle="Solid"  BorderColor="Maroon" ForeColor="White" />
          
        </ContentTemplate>
       
    </asp:UpdatePanel>
</asp:Content>

Также у нас имеется контрол Preloader.ascx который  отображает какую-то информацию пока происходит обработка и выполнение запроса.
<%--A simple Div that shows us "Loading" message.--%>
<div style="top:150px; width:100%; left:0px; display:block;position:fixed; z-index:2000;" align="center" >
    <table style=" width:600px; height:200px; z-index:2002; background-color:#f9f9f9; border-style:solid; border-color:Grey; ">
        <tr>
            <td valign="middle" align="center">
                <h1 style=" color:Navy">Loading: 5000 milliseconds...</h1>
            </td>
        </tr>     
    </table>
</div>
Согласно исходным данным, при нажатии кнопки   btnWithPostBackTrigger мы не увидим никакой так называемой  "ПрогрессИнформации". Если же мы нажмем на другую кнопку то  мы увилим эту "ПрогрессИнформацию". Но это не очень удобно... В одном случае приложение информирует нас о том что оно что-то делает, в другом нет. Хотя в обоих случаях приложение занято какими-то вычислениями. Было бы гораздо  удобнее информировать пользователя о работе приложения в обоих случаях, вне зависимости от типов постбека.

Исследование.
Существуют различные способы решить эту проблему. Но я предпочитаю использовать самый простой (для меня)  сопособ. И это эмуляция отображения "ПрогрессИнформации" для АпдейтПанели.

Решение.
Идея в следующем - запускать клиентский  код (JavaScript) по нажатию на нашу btnWithPostBackTrigger. В любом случае этот код будет запущен и исполнен до того момента как запрос уйдет на сервер, обработается там, и вернется назад.  Мы нажимаем кнопку и посредством нашего клиентского кода показываем "ПрогрессИнформацию".  И пока запрос не вернулся от сервера мы видим нашу "ПрогрессИнформацию". При таком подходе нам также не надо думать о том как прятать "ПрогрессИнформацию" когда все закончится, потому что когда  запрос вернется от сервера - вся страница полностью перерисуется (у нас полный постбек) . А так как "ПрогрессИнформацию" у нас по умолчанию спрятана - то она исчезнет автоматически после перерисовки страницы.

Теперь небольшие измения висходном коде для реализации всего вышеописанного...
<div id="divPreloader" style="visibility:hidden;">
      <uc1:Preloader    ID="ucPre"  runat="server" />
</div>
Добавляем этот код где-то за пределами АпдейтПанели. Это то что  пользователь будет видеть при полном постбеке. Я расположил его над АпдейтПанелью. Мы будем находить  и показывать этот  див с помощь клиенсткого скрипта.
И добавим OnClientClick="ShowProgress('divPreloader')" к нашей кнопке btnWithPostBackTrigger. в нашем случае ShowProgress - это название джаваскриптовой функции которая будет показывать то, что нам надо.

Измения в .vbфале...
Private Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim PageLoadedHandlerScript As String = " function getObject (sId) { if(!sId) return null; else if (document.all && document.all[sId])  return document.all[sId];  else if (document.getElementById)  return document.getElementById(sId); else return null;}" _
         & " function ShowProgress(sId) { var dP = getObject(sId); if (dP != null) { dP.style.visibility = 'visible'; } }"
        Page.ClientScript.RegisterClientScriptBlock(Me.GetType, "getObjectScript", PageLoadedHandlerScript, True)
        btnWithPostBackTrigger.OnClientClick = "ShowProgress('divPreloader')"
End Sub
В этом куске кода мы регистрируем клиентский скрипт на странице. В нем две функции. Первая функция ищет DOM обьект на странице. Вторая функция показывает найденный див. Если хотите используйте свой собственный  JavaScript и jQuery.

Вот и все. Надеюсь это поможет вам.

English version of this  post >>
to sources >>
WWW.LANTERIA.COM

понедельник, 19 марта 2012 г.

Экспорт в excel/word возвращает пустой документ или снова проблемы с ReportViewer 2010 в SharePoint 2010

Исходные данные.
Исходные данные такие же как и в предыдущем сощбщении: SharePoint 2010 -> Visual Web Part -> UpdatePanel -> Microsoft Report Viewer 2010.

Ситуация.
MRV 2010 корректно генерирует рапорт на страничке в своей секции. НО когда мы тыцаем на "Export to Excel/Word" и пытаемя открыть сгенерированный документ, то     во-первых мы получаем следущее предупреждение  "The file you are trying to open '<FileName.xls>', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?". Во-вторых - если мы соглашаемся открыть документ - то получаем пустоту размером в 0 кб.

Исследование.
Если залогиниться как пользователь который имеет админские права на сервере и сэкспортировать документ в вышеуказанные форматы - то все хорошо. Никаких предупреждений. Да и документы не пустые. Но стоит только зайти как  обычный пользователь - "Хьюстон, у нас проблемы". Так что проблемы где-то в правах на сервере.
Посредством полезной утилитки Procees Monitor обнаружил что Network Service имеет ошибку записи при попытке записать екселевский файлик в некоторый каталог. Это был знак. 

Решение.
Вот этот каталог -  "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp".  Для того чтоб решить эту проблему достаточно было добавить пользователя  "Authenticated Users" с правами   "Full Control " на эту директорию.

НО! Это не совсем правильный ответ.... Каталог описанный выше - это всего лишь частный случай... На самом деле нужно сделать следущее -  добавить пользователя  "Authenticated Users" с правами   "Full Control " на временную директорию аккаунта под которым выполняется Пул вашего веб-приложения. У меня Пул запускался как Network Service - так что вышеописанная директория мне подошла. Но если ваш пул запускается, например, под пользователем "Administrator.Office" - то возможно, вам понадобится эта директория: C:\Users\Administrator.OFFICE\AppData\Local\Temp. Да, и делайте все это на сервере, а не на локальной машине.



English version of this  post >>
WWW.LANTERIA.COM

пятница, 17 февраля 2012 г.

Проблемы ReportViewer2010 + UpdatePanel + SharePoint2010 в Chrome и Safary или Uncaught Sys.ScriptLoadFailedException: Sys.ScriptLoadFailedException: The script '.....' could not be loaded. Uncaught TypeError: Cannot read property '_notified' of null.

Исходные данные.
Имеем ВебПарт(WebPart) для SharePoint2010. В этом вебпарте находится АпдейтПанель (UpdatePanel).  В апдейтпанели имеем соответственно РепортВьювер10 (ReportViewer 10).

Ситуация.
 В IE9.0 и Firefox рапорт отображается корректно. А вот в Chrome и Safari ничего не отображается. Вернее отображается НЕ активный репортвьювер контрол, без контента. Причем если убираем апдейтпанель - то рапорт начинает корректно отображаться во всех броузерах.  При попытке смоделировать подобную ситуацию посредством обычного веб-сайта созданного через VS2010 (апдейт панель + репорт вьювер) никаких ошибок не возникает. А вот в SharePoint2010 имеется...

Исследование.
Через хромовый девелопер тул (F12) определил что возикает две джаваскриптовые ошибки
1.Uncaught Sys.ScriptLoadFailedException: Sys.ScriptLoadFailedException: The script '....' could not be loaded.
2. Uncaught TypeError: Cannot read property '_notified' of null
и все это в файле MicrosoftAjaxWebForms.js...


Решение.
Порывшись в инете нашел что подобная ошибка возникает частенько с этими браузерами при использовнии UpdatePanel/AjaxToolkit - все что использует ScriptManager. MicrosoftAjax одним словом... Проблема заключается в том что в MicrosoftAjaxWebForms.js  не корректно определяются WebKit-овские броузеры. Если добавить на страницу следующий код :

Sys.Browser.WebKit = {};
if (navigator.userAgent.indexOf('WebKit/') > -1) {
    Sys.Browser.agent = Sys.Browser.WebKit;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = 'WebKit';
}

то все начинает работать корректно. Такое впечатление что корректный джаваскрипт для  работы этих броузеров присутствует, а вот определитель работает не корретно. В общем эти строчки решили проблему. Но остается вопрос - почему это происходило в   SharePoint2010 и не просходило на простом вебсайте. Единственное обьяснение которое я вижу - это то что используются различные версии аджаксовых скриптов для этих продуктов.


English version of this post >>
WWW.LANTERIA.COM

вторник, 14 февраля 2012 г.

ASP.NET 4.0 ClientID Overview

Четкие статьи описывающие различные принципы формирования/использования ClientID для контролов сгенерированных ASP.NET на клиентской стороне.

ССЫЛКА НА СТАТЬЮ №1 >>
ССЫЛКА НА СТАТЬЮ №2 >>

WWW.LANTERIA.COM