Friday, October 9, 2009

C#: Serialize an object to Xml (string)

Especially useful if the object is not inheriting the [Serializable] attribute...


string GetSerializedXmlString(object obj)
{
MemoryStream memoryStream = new MemoryStream();
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xmlSerializer.Serialize(xmlTextWriter, obj);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
UTF8Encoding encoding = new UTF8Encoding();
return encoding.GetString(memoryStream.ToArray());
}

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

Monday, June 29, 2009

C#: Write a file from an URL response

public void WriteFileContentsFromUrl(string contentUrl, string filePath)
{
WebClient request = new WebClient();
request.UseDefaultCredentials = true;
byte[] fileContent = request.DownloadData(contentUrl);
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(fileContent);
bw.Close();
}

Sunday, May 31, 2009

C#: Execute Two Dependant Processes (2 Starts After 1 Finishes)

Gunjan asked about this in one of my other threads:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace DriverApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press Enter to start Notepad (i.e. Process 1)");
Console.ReadKey();
Console.WriteLine("Starting Notepad...");
Thread t1 = new Thread(new ThreadStart(StartProcess1));
t1.Start();
while (t1.IsAlive == true)
{
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Notepad Stopped. Starting MSPaint (i.e. Process 2)");
StartProcess2();
Console.WriteLine("MSPaint Stopped. Press Enter to Exit");
Console.ReadKey();
}

static void StartProcess1()
{
Process proc = new Process();
proc.StartInfo.FileName = "Notepad.exe";
proc.Start();
Console.WriteLine("Notepad running...");
proc.WaitForExit();
}

static void StartProcess2()
{
Process proc = new Process();
proc.StartInfo.FileName = "MSPaint.exe";
proc.Start();
Console.WriteLine("MSPaint running...");
proc.WaitForExit();
}
}
}

Friday, April 10, 2009

Thursday, April 9, 2009

C#: Create WindowsIdentity From UserID and Password

Important: The code must be compiled with /unsafe flag

using System.Security;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
...

WindowsIdentity LogonUserAndGetWindowsIdentify(string userId, string password, string domainId)
{
IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

bool rcBool = LogonUser(userId, domainId, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
if (!rcBool)
throw new Exception("Error while trying to log user on");

rcBool = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
if (!rcBool)
throw new Exception("Error while trying to duplicate token");

WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);

CloseHandle(tokenHandle);
CloseHandle(dupeTokenHandle);

return newId;
}

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

public unsafe static string GetErrorMessage(int errorCode)
{
int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;

int messageSize = 255;
String lpMsgBuf = "";
int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;

IntPtr ptrlpSource = IntPtr.Zero;
IntPtr prtArguments = IntPtr.Zero;

int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
if (0 == retVal)
{
throw new Exception("Failed to format message for error code " + errorCode + ". ");
}

return lpMsgBuf;
}

Monday, March 16, 2009

C#: Convert Non-Seekable Stream to Byte Array

byte[] ConvertNonSeekableStreamToByteArray(Stream NonSeekableStream)
{
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
int bytes;
while ((bytes = NonSeekableStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, bytes);
}
byte[] output = ms.ToArray();
return output;
}

Friday, January 30, 2009

C#: Generic Error Handling Routine (WinApp)

Just call the LogError method from any function within the catch block and pass the exception (ex) to this method...

public static void LogError(Exception ex)
{
string EventLogSourceName = "Application Name";
int EventLogErrorCode = "99";
string msg = "The application encountered an unknown error:";
msg += "\r\nExecuting Method: " + new System.Diagnostics.StackFrame(1, false).GetMethod().Name;
msg += "\r\nError Message: " + ex.Message;

EventLog.WriteEntry(EventLogSourceName, msg, EventLogEntryType.Error, EventLogErrorCode);
MessageBox.Show(msg, "ERROR", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
}