Modelul asincron din ASP.NET
Sa discutam despre operatii asincrone in ASP.NET.
Exista doua tipuri mari de operatii operatii asincrone
1. Cele care se executa doar
pentru operatii lungi , care iau ceva timp de executie, si pentru care user-ul
trebuie instiintat de evolutia lor.
2. Cele care trimit rapid o
cerere la server si se intorc.
Pentru 1.,o solutie recomandata este sa puneti Async=true in
codul de pagina si sa executati codul cu RegisterTaskAsync . Asta este
interesant, pina cind ne dam seama ca modul de afisare al paginii este acelasi
– adica este intirziata pina cind se termina toata de executat.
Un exemplu bun gasiti aici
http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/#S5
si aici
http://msdn.microsoft.com/msdnmag/issues/07/03/WickedCode/default.aspx
Totusi, as recomanda o alta abordare – pentru ca user-ul sa
„vada” desfasurarea detaliata a actiunilor efectuate, as recomanda scrierea cu
Response.Write intr-un div si ascunderea apoi a div-ului .
Ceva de genul acesta:
Pe pagina aspx, printre ultimele linii, ascunderea div-ului
cu mesaje:
<script>
var mesaje =
document.getElementById(‘mesaje’);
if(mesaje != null)
mesaje.style.display = ‘none’;
</script>
In codul paginii aspx putem pune cod de genul urmator:
Response.Write(“<div
id=’mesaje’>”);
Response.Write(“Begin :” + DateTime.Now.ToString(“yyyy MMM dd hh:mm:ss”) + “<BR>”);
Response.Flush();
//executare prim task
Response.Write(“Generated
prim task<BR>”);
Response.Flush();
//executare al doilea task
Response.Write(“Generated
al doilea task<BR>”);
Response.Flush();
//incheiere procedura…
Response.Write(“</div>”);
Response.Flush();
Acest model se poate combina cu evenimente generate in
cadrul task-ruilor astfel incit, daca task-urile dureaza prea mult, user-ul sa
aiba totusi un feedback despre ceea ce se intimpla.
Sa discutam acum despre 2, executarea de operatii rapide pe
server. Sa dam un exemplu simplu, si anume cautarea de publisher dupa nume. Ar
fi superb daca aplicatia noastra, la apasarea primei litere a publisher-ului,
ar putea sa sugereze publisher-ii care incep cu litera respectiva.
Pentru aceasta vom folosi Ajax,
si vom folosi implementarea de AutoComplete
de la Ajax
Control Toolkit
Mai intii ,trebuie sa downloadam Ajax1.0 de aici.
Apoi va trebui sa modificam Web.Config astfel incit sa
suporte Ajax.
Asta inseamna ca o sa luam o mare parte din Web.Config-ul
unui site Ajax si o sa il mutam la noi in site.
Sa incepem :
De la o configuration o sa luam
<configSections>
<sectionGroup name=“system.web.extensions“ type=“System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35“>
<sectionGroup name=“scripting“ type=“System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“>
<section name=“scriptResourceHandler“ type=“System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“ requirePermission=“false“ allowDefinition=“MachineToApplication“/>
<sectionGroup name=“webServices“ type=“System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“>
<section name=“jsonSerialization“ type=“System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“ requirePermission=“false“ allowDefinition=“Everywhere“/>
<section name=“profileService“ type=“System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“ requirePermission=“false“ allowDefinition=“MachineToApplication“/>
<section name=“authenticationService“ type=“System.Web.Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“ requirePermission=“false“ allowDefinition=“MachineToApplication“/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
De la system.web o sa luam
<pages>
<controls>
<add tagPrefix=“asp“ namespace=“System.Web.UI“ assembly=“System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“/>
</controls>
</pages>
Si
<compilation debug=“false“>
<assemblies>
<add assembly=“System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“/>
<add assembly=“System.Design, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=B03F5F7F11D50A3A“/>
<add assembly=“System.Web.Extensions.Design, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35“/></assemblies>
</compilation>
Apoi Handler-e si Module:
<httpHandlers>
<remove verb=“*“ path=“*.asmx“/>
<add verb=“*“ path=“*.asmx“ validate=“false“ type=“System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“/>
<add verb=“*“ path=“*_AppService.axd“ validate=“false“ type=“System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“/>
<add verb=“GET,HEAD“ path=“ScriptResource.axd“ type=“System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“ validate=“false“/>
</httpHandlers>
<httpModules>
<add name=“ScriptModule“ type=“System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35“/>
</httpModules>
Apoi extensions si WebServer:
<system.web.extensions>
<scripting>
<webServices>
<!– Uncomment this
line to customize maxJsonLength and add a custom converter –>
<!–
<jsonSerialization maxJsonLength=”500″>
<converters>
<add
name=”ConvertMe”
type=”Acme.SubAcme.ConvertMeTypeConverter”/>
</converters>
</jsonSerialization>
–>
<!– Uncomment this
line to enable the authentication service. Include requireSSL=”true”
if appropriate. –>
<!–
<authenticationService
enabled=”true” requireSSL = “true|false”/>
–>
<!– Uncomment these
lines to enable the profile service. To allow profile properties to be
retrieved
and modified in ASP.NET AJAX
applications, you need to add each property name to the readAccessProperties
and
writeAccessProperties
attributes. –>
<!–
<profileService
enabled=”true”
readAccessProperties=”propertyname1,propertyname2″
writeAccessProperties=”propertyname1,propertyname2″ />
–>
</webServices>
<!–
<scriptResourceHandler
enableCompression=”true” enableCaching=”true” />
–>
</scripting>
</system.web.extensions>
<system.webServer>
<validation validateIntegratedModeConfiguration=“false“/>
<modules>
<add name=“ScriptModule“ preCondition=“integratedMode“ type=“System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35“/>
</modules>
<handlers>
<remove name=“WebServiceHandlerFactory-Integrated“/>
<add name=“ScriptHandlerFactory“ verb=“*“ path=“*.asmx“ preCondition=“integratedMode“ type=“System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“/>
<add name=“ScriptHandlerFactoryAppServices“ verb=“*“ path=“*_AppService.axd“ preCondition=“integratedMode“ type=“System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35“/>
<add name=“ScriptResource“ preCondition=“integratedMode“ verb=“GET,HEAD“ path=“ScriptResource.axd“ type=“System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35“/>
</handlers>
</system.webServer>
Acum downloadam Ajax
Control Toolkit si vom referentia controalele existente, aflate in AjaxControlToolkit-NoSource\SampleWebSite\Bin
. Vom adauga un nou tab in ToolBox, ii vom zice AjaxControls si vom adauga
itemii apasind pe Choose Items:
Si apoi indicind prin browse calea la AjaxControlToolkit.dll
pe care l-am downloadat. Apasati pe urma OK si vom avea controalele Ajax.
Trageti un AutoCompleteExtender si un textbox in frmPublisherList.aspx
.
Vom completa
public
class wsPublisher
: System.Web.Services.WebService {
cu atributul
[System.Web.Script.Services.ScriptService]
si vom adauga o metoda pentru regasirea publisher-ilor care
incep cu o litera data:
[WebMethod]
public string[] GetCompletionPublishers(string prefixText, int
count)
{
if (count
<= 0)
count = 10;
List<string> items = new
List<string>(count);
BookObjects.ColPublisher
publishers = new BookObjects.ColPublisher();
publishers.Load();
foreach
(BookObjects.Publisher pub in publishers)
{
if
(pub.Name.IndexOf(prefixText, StringComparison.CurrentCultureIgnoreCase)
== 0)
items.Add(pub.Name);
if
(items.Count == count)
break;
}
return
items.ToArray();
}
O vom folosi in Autocomplete:
<asp:ScriptManager runat=”server”>
</asp:ScriptManager>
<asp:TextBox ID=”txtPub” runat=”server” autocomplete=”off”></asp:TextBox>
<cc1:AutoCompleteExtender ID=”AutoPub” runat=”server”
TargetControlID=”txtPub”
ServicePath=”wsPublisher.asmx”
ServiceMethod=”GetCompletionPublishers”
MinimumPrefixLength=”1″
CompletionInterval=”1000″
EnableCaching=”true”
CompletionSetCount=”12″>
</cc1:AutoCompleteExtender>
In momentul de fata putem testa aplicatia si vedea ca se
listeaza numele publisher-ilor.
Lucruri de facut:
Creat o metoda prin care sa se poata incarca doar cei care
au prefix, nu toti publisher-ii cum am facut in public string[]
GetCompletionPublishers(string prefixText, int count)
De pus scriptManager-ul in Master- ca sa nu fim nevoiti sa
il punem in fiecare pagina.
De vazut celelalte controale de la Ajax
Control Toolkit (live demo la adresa http://ajax.asp.net/ajaxtoolkit/Default.aspx
)
Data viitoare vom vorbi despre scoaterea de rapoarte .