Web Application Architecture (ASP.NET 3.5,JavaScript) - asp.net

hey all ,
background -
I'm using an activx that allow me to access some information on the client side,
By using the activex events and callback i'm updating server side from client.
i wrote a user control that register all activex's events so when one of the events occuer there is a callback to the server that handle this event.
I need to write some other user controls based on this control so on every callback this user controls will be render on the client side.
My question is -
what is the best way to make a shared infrastructure that handle this events and render the right content base on user controls?
is there any other ways i can use ?
thanks!
hey! thanks for your fast reply,
first of all , i'm calling the activex using object tags,
HtmlGenericControl SkypeObject = new HtmlGenericControl("object");
SkypeObject.Attributes.Add("id", "Skype");
SkypeObject.Attributes.Add("codeBase", "http://ip/Skype4COM.dll");
SkypeObject.Attributes.Add("classid", "clsid:830690FC-BF2F-47A6-AC2D-330BCB402664");
SkypeObject.Attributes.Add("name", "Skype");
write callback :
string SkypeAsyncCallbackOnEvent = ClientScript.GetCallbackEventReference(this, "values", ClientScriptName, "context", true);
string SkypeCallbackFunction = "\n<script>\n";
SkypeCallbackFunction += "function SkypeCallback(values,context) {\n";
SkypeCallbackFunction += SkypeAsyncCallbackOnEvent + "\n}\n";
SkypeCallbackFunction += "</script>";
then i register the active'x events :
string SkypeOnUserStatusChange = "\n<script for=\"Skype\" event=\"UserStatus(Status)\">\n";
SkypeOnUserStatusChange += "var values = {\"StatusInfo\" : Status};\n";
SkypeOnUserStatusChange += "var myArray = {\"key\" : \"Status\", \"values\" : values};\n";
SkypeOnUserStatusChange += "var s=JSON.stringify(myArray);";
SkypeOnUserStatusChange += "SkypeCallback(s,null);\n";
SkypeOnUserStatusChange += "</script>";
this is my base user control (in short) so on each events callback is occur.
(this can be change to any class it doesnt metter right now)
now i want to create custom controls that will show the data back from the client.
in my opinion, i can change the call back reference client script to the one that exist in the Child Control and register the child control to the events of the base control.
what do you think ?
thanks :)

A little more info on your project would be helpful, but I think you would be well served using two approaches, one to handle the logic/events... and one to actually handle the visual updates - with some glue in the middle to make it all work like a charm.
First, the events. I could envision some sort of javascript class that registers with your activex control and binds methods to the various event handlers. This class would also expose methods you could bind functions to that would provide callbacks to your display logic.
Second, I would recommend using a library like jQuery to help with the heavy lifting of modifying the user page.
function eventTrap() {}
eventTrap.prototype.hookActiveX() { // your code to attach to your activex object }
eventTrap.prototype.register(event, callback) { // code to register for an event and callback }
// actually use it...
var trapObj = new eventTrap();
trapObj.hookActiveX();
trapObj.register("click", function(){alert('click');});

Related

.xproj does not throw ItemAdded event

I want my extension to do something everytime an item gets added to the project. This works fine for normale Projects or, with some magic (see here), for the Project Type "Website". But i cant get it to work with .xproj.
Here my current code to access the ItemAdded event (shortened)
var events = _dte.Events as Events2;
_projectItemEvents = events.ProjectItemsEvents;
_projectItemEvents.ItemAdded += ItemAdded;
_websiteItemEvents = events.GetObject ("WebSiteItemsEvents") as ProjectItemsEvents;
_websiteItemEvents.ItemAdded += ItemAdded;
_csharpItemEvents = events.GetObject ("CSharpProjectItemsEvents") as ProjectItemsEvents;
_csharpItemEvents.ItemAdded += ItemAdded;
Does anyone know how to access the ItemAdded event in case of an .xproj project type?
Edit: Edited code; The variables are all class fields and are not garbage collected, as in case of the other project types, the events are fired properly, just not in case of an .xproj.

How to open new window with streamed document in ASP.NET Web Forms

I have an ASP.NET Web Forms application. I want to have a button to post back to the server that will use my fields on my form (after validation) as parameters to a server process that will generate a document and stream it back to the browser. I want the form to be updated with some status results.
What is the best way to achieve this? Right now, I've got the button click generating the document and streaming it back to the browser (it's a Word document and the dialog pops up, and the Word document can be opened successfully) but the page doesn't get updated.
I have jQuery in my solution, so using js isn't an issue if that is required.
I have a very similar process on one of my servers, and the way I've handled it is to create a temporary document on the server rather than doing a live stream. It requires a bit of housekeeping code to tidy it up, but it does mean that you can return the results of the generation and then do a client-side redirect to the generated document if successful. In my case, I'm using jQuery and AJAX to do the document generation and page update, but the same principle should also apply to a pure WebForms approach.
This was way more difficult to do than I thought. The main issue is with opening a new browser window for a Word document. The window briefly flashes up, then closes - no Word document appears. It seems to be a security issue.
If i click a button on my page, I can stream the Word doc back as the response, and the browser dialog pops up allowing me to Open/Save/Cancel, but of course, my page doesn't refresh.
My final solution to this was to use a client script on the button click to temporarily set the form's target to _blank. This forces the response to the click on the postback to go to a new browser window (which automatically closes after the download dialog is dismissed):
<asp:Button Text="Generate Doc" runat="server" ID="btnGenerateDoc"
onclick="btnGenerateDoc_Click" OnClientClick="SetupPageRefresh()" />
My SetupPageRefresh function is as follows:
function SetupPageRefresh() {
// Force the button to open a new browser window.
form1.target = '_blank';
// Immediately reset the form's target back to this page, and setup a poll
// to the server to wait until the document has been generated.
setTimeout("OnTimeout();", 1);
}
Then my OnTimeout function resets the target for the form, then starts polling a web service to wait until the server process is complete. (I have a counter in my Session that I update once the process has completed.)
function OnTimeout() {
// Reset the form's target back to this page (from _blank).
form1.target = '_self';
// Poll for a change.
Poll();
}
And the Poll function simply uses jQuery's ajax function to poll my web service:
function Poll() {
var currentCount = $("#hidCount").val();
$.ajax({
url: "/WebService1.asmx/CheckCount",
data: JSON.stringify({ currentCount: currentCount }),
success: function (data) {
var changed = data.d;
if (changed) {
// Change recorded, so refresh the page.
window.location = window.location;
}
else {
// No change - check again in 1 second.
setTimeout("Poll();", 1000);
}
}
});
}
So this does a 1 second poll to my web service waiting for the Session's counter to change from the value in the hidden field on the page. This means it doesn't matter how long the server process takes to generate the Word document (and update the database, etc.) the page won't refresh until it's done.
When the web service call comes back with true, the page is refreshed with the window.location = window.location statement.
For completeness, my Web Service looks like this:
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WebService1 : WebService
{
[WebMethod(EnableSession=true)]
public bool CheckCount(int currentCount)
{
if (Session["Count"] == null)
Session["Count"] = 0;
var count = (int)Session["Count"];
var changed = count != currentCount;
return changed;
}
}
Hopefully that helps somebody else!

Popup a CalendarBehavior from Javascript

How can I embbed all the scripts needed by the CalendarBehavior in a page, without actually using the server-side control (CalendarExtender). The reason I can't use a server side extender is that I have a page with, possibly, hundreds of Date controls; I want to be able lazy-load the calendars as needed (when the user clicks in the control).
The code that creates the calendar from javascript is the following:
cal = $create(AjaxControlToolkit.CalendarBehavior,
{ 'id': owner.id + '_calendar', 'cssClass': 'calExt', 'format': format },
null, null, owner);
The problem is that without including all the needed js from the AjaxControlToolkit resources, it will throw the error:
AjaxControlToolkit is undefined.
Thank you very much,
Florin S.
I've found the following hack that will register all the scripts and css references exposed by the CalendarExtender. I think the solution is generic so that it can be used with other extenders:
ScriptManager manager = ScriptManager.GetCurrent(Page);
if (manager != null)
{
foreach (ScriptReference reference in ScriptObjectBuilder.GetScriptReferences(typeof(CalendarExtender)))
{
manager.Scripts.Add(reference);
}
CalendarExtender extender = new CalendarExtender();
Page.Form.Controls.Add(extender);
ScriptObjectBuilder.RegisterCssReferences(extender);
Page.Form.Controls.Remove(extender);
}
The temporary extender instance is needed for the RegisterCssReferences call, otherwise it will throw an error.
It works, but YMMV.
I had the same issue.
I found that, in javascript-land, instead of AjaxControlToolkit you should use Sys.Extended.UI.
So, instead of:
cal = $create(AjaxControlToolkit.CalendarBehavior, ...
you do this:
cal = $create(Sys.Extended.UI.CalendarBehavior, ...

Passing flash variables to asp.net

I don't know much about Flash but we are working on a site that has a flash form and when the users pick an option, like selecting a value from a drop down list, we need the value to be passed to asp.net server-side code. What's the easiest way to do this?
Flash can invoke server side service. So use GET or POST to pass data
You could explore these options:
1) Communicate between the SWF and the containing page through JavaScript
2) Communicate via asp.net webservices from the SWF directly to the webservice.
3) Not sure but could probably do a POST to a processing aspx page?
HTH
I think a good option is to use the XML class so consider this:
var xmlRequest = new XML();
xmlRequest.onLoad = parseXMLResponse;
xmlRequest.load("http://yourpathtoyourserver/file.aspx?listselectedvalue=something");
function parseXMLRequest(loaded)
{
trace("hi");
}
You can also have the page give you data back this way so it's not just one way communication.
Assuming you are using Action Script 2.
Read the important notes at the bottom of each codes pertain to sending and retrieving data from flash to .net page. Explanation of the code is in the comment inside the code.
Flash Part (Action Script 2)
//function to send collected form data to asp.net page
//use other control/button to call this function
//important: in order for the 'onLoad' event to work correctly, this function has to be 'Void'
function sendForm():Void
{
//create LoadVars object
var lv_in:LoadVars = new LoadVars();
var lv_out:LoadVars = new LoadVars();
//set onLoad event
lv_in.onLoad = function(success:Boolean)
{
//if success, meaning data has received from .net page, run this code
if (success)
{
//lv_in.status is use to get the posted data from .Net page
statusMsg.text = "Thank you for filling up the form!" + lv_in.status;
}
//if fail, run this code
else
{
statusMsg.text = "The form you are trying to fill up has an error!";
}
}
//this is the collected data from the form
lv_out.userName = txtUserName.text;
lv_out.userAddress = txtUserAddress.text;
lv_out.userBirthday = txtUserBirthday.text;
//begin invoke .net page
lv_out.sendAndLoad("ProcessDataForm.aspx", lv_in, "POST");
}
Important note:
The function that contain onLoad event, in this case sendForm function, has to be Void function, meaning it's not returning value. If this function return value, what happen is the function will be executed all the way without waiting for the returned data from .net page, thus the onLoad event will not be set properly.
.Net Part
public void ProcessData
{
//process the data here
Response.Write("status=processed&");
}
Important note:
To send data/message back to flash, you can use Response.Write. However, if you want Action Script to parse the posted message/data from .Net page keep in mind you have to include & symbol at the end of the message. When parsing data/message, Action Script will stop at & symbol, thus leave the rest of the message alone and only get the message under sent variable.

ASP.Net Custom Client-Side Validation

I have a custom validation function in JavaScript in a user control on a .Net 2.0 web site which checks to see that the fee paid is not in excess of the fee amount due.
I've placed the validator code in the ascx file, and I have also tried using Page.ClientScript.RegisterClientScriptBlock() and in both cases the validation fires, but cannot find the JavaScript function.
The output in Firefox's error console is "feeAmountCheck is not defined". Here is the function (this was taken directly from firefox->view source)
<script type="text/javascript">
function feeAmountCheck(source, arguments)
{
var amountDue = document.getElementById('ctl00_footerContentHolder_Fees1_FeeDue');
var amountPaid = document.getElementById('ctl00_footerContentHolder_Fees1_FeePaid');
if (amountDue.value > 0 && amountDue >= amountPaid)
{
arguments.IsValid = true;
}
else
{
arguments.IsValid = false;
}
return arguments;
}
</script>
Any ideas as to why the function isn't being found? How can I remedy this without having to add the function to my master page or consuming page?
Try changing the argument names to sender and args. And, after you have it working, switch the call over to ScriptManager.RegisterClientScriptBlock, regardless of AJAX use.
When you're using .Net 2.0 and Ajax - you should use:
ScriptManager.RegisterClientScriptBlock
It will work better in Ajax environments then the old Page.ClientScript version
Also you could use:
var amountDue = document.getElementById('<%=YourControlName.ClientID%>');
That will automatically resolve the client id for the element without you having to figure out that it's called 'ctl00_footerContentHolder_Fees1_FeeDue'.
While I would still like an answer to why my javascript wasn't being recognized, the solution I found in the meantime (and should have done in the first place) is to use an Asp:CompareValidator instead of an Asp:CustomValidator.

Resources