Thursday, September 17, 2009

C#: Read content as byte[] from an URL

public byte[] GetUrlResponse(string contentUrl)
{
WebClient request = new WebClient();
request.UseDefaultCredentials = true;
byte[] contentBytes = request.DownloadData(contentUrl);
return contentBytes;
}

C#: Stub code for writing ActiveX components

Here is the base code for writing the ActiveX component, this needs to be followed by instructions for setup etc. as documented here

***********************
Class: ActiveXDotNet.cs
***********************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//Additionally added for ActiveX
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Windows.Forms;

namespace NSActiveXDotNet
{
[Guid("E86A9038-368D-4e8f-B389-FDEF38935B2F"), InterfaceType(ComInterfaceType.InterfaceIsDual), ComVisible(true)]
public interface IActiveXDotNet
{
[DispId(1)]
void ShowDialog(string message);
};

[Guid("B769DA4B-FDDD-41BD-BDD2-7101D08E8E0C"), ClassInterface(ClassInterfaceType.None),
ComDefaultInterface(typeof(IActiveXDotNet)), ComVisible(true), ProgId("ActiveXDotNet.CActiveXDotNet")]
public class CActiveXDotNet : IObjectSafetyImpl, IActiveXDotNet
{

#region IActiveXDotNet Members

public void ShowDialog(string message)
{
MessageBox.Show(message, "Message From ActiveX", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

#endregion
}
}


***********************
Class: IObjectSafety.cs
***********************

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Text;

namespace NSActiveXDotNet
{
[
Serializable,
ComVisible(true)
]
public enum ObjectSafetyOptions
{
INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
INTERFACE_USES_DISPEX = 0x00000004,
INTERFACE_USES_SECURITY_MANAGER = 0x00000008
};

//
// MS IObjectSafety Interface definition
//
[
ComImport(),
Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IObjectSafety
{
[PreserveSig]
long GetInterfaceSafetyOptions(ref Guid iid, out int pdwSupportedOptions, out int pdwEnabledOptions);

[PreserveSig]
long SetInterfaceSafetyOptions(ref Guid iid, int dwOptionSetMask, int dwEnabledOptions);
};

//
// Provides a default Implementation for safe scripting.
// This basically means IE won't complain about the ActiveX object not being safe
//
public class IObjectSafetyImpl : IObjectSafety
{
private ObjectSafetyOptions m_options =
ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER |
ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;

#region [IObjectSafety implementation]
public long GetInterfaceSafetyOptions(ref Guid iid, out int pdwSupportedOptions, out int pdwEnabledOptions)
{
pdwSupportedOptions = (int)m_options;
pdwEnabledOptions = (int)m_options;
return 0;
}

public long SetInterfaceSafetyOptions(ref Guid iid, int dwOptionSetMask, int dwEnabledOptions)
{
return 0;
}
#endregion
};
}

C#: Stream document to open within browser

Note: This is not full proof, flavor of browser and local settings would probably override things.

void StreamDocumentInline(byte[] content, string mimeType)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("Content-Length", content.Length.ToString());
Response.AddHeader("Content-Type", mimeType);
Response.AddHeader("Content-Disposition", "inline");
Response.BinaryWrite(content);
Response.Flush();
Response.End();
}

C#: Stream document through browser to open in native application

void StreamDocumentToNativeApp (byte[] content, string fileName, string mimeType)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
Response.AddHeader("Content-Length", content.Length.ToString());
Response.AddHeader("Content-Type", mimeType); //Example application/text
Response.BinaryWrite(content);
Response.Flush();
Response.End();
}

Tuesday, September 15, 2009

C#: Efficiently (somewhat) deal with large ViewState

If you are REALLY worried about having the most efficient method of saving ViewState, you should be using the SQLStateServer approach. However if you want a quick hack that will work quite efficiently as long as you do not have hundreds and thousands of active users, you can continue reading this post. Needless to say, I am assuming you have turned EnableViewState to off for whatever controls you could (labels etc), and are concerned about only the ones where you must save the view state.

OK here we go! As we know ASP .Net handles a Cache object (or even Session for that matter) much more efficiently than it does ViewState, just add these two methods in your code behind to save the ViewState to the server cache customized for the user, and restore from it later, in stead of putting it within the page itself.

(Note: You might also consider using a Session object in stead of cache for that matter)

//Just embed these two methods within the codebehind of the page
#region Hack to save and restore ViewState to and from Cache
protected override void SavePageStateToPersistenceMedium(object viewState)
{
// Generate unique key for this viewstate
string stateToSave = "VIEWSTATE#" + Request.UserHostAddress + "#" + DateTime.Now.Ticks.ToString();
// Save viewstate data in cache
Cache.Add(stateToSave, viewState, null, DateTime.Now.AddMinutes(Session.Timeout), TimeSpan.Zero, CacheItemPriority.Default, null);
// Save key in a hidden field
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", stateToSave);
}

protected override object LoadPageStateFromPersistenceMedium()
{
// Load back viewstate from cache
string savedState = Request.Form["__VIEWSTATE_KEY"];
// Check validity of viewstate key
if (!savedState.StartsWith("VIEWSTATE#"))
throw new Exception("Invalid viewstate key:" + savedState);
object savedCache = Cache[savedState];
// Cleanup the saved cache from server memory
Cache.Remove(savedState);
return savedCache;
}
#endregion