Tuesday, July 24, 2007

2010, a "Windows 7" software subscription odyssey

Microsoft has again confirmed that the "big release" approach to software development is alive and well at Microsoft. Ballmer said as much earlier this year in advance of the retail Vista launch, but the company is reiterating the point now as it ramps up preparation for the next version of Windows and a renewed push for software subscriptions.

read more | digg story

Thursday, July 19, 2007

Send Web User Control as Email

I often have to setup an application to auto-send emails. I use a user control as the body of the email to save time formatting the HTML.

private string getSupervisorEmailContent()
{
    string content;
 
    // create and populate an instance of a ContentControl user control
    EmailSupervisor cc = (EmailSupervisor)this.LoadControl("EmailSupervisor.ascx");
    cc.EmployeeName = this.lblEmployeeName.Text;
    cc.SystemLink = "http://" + HttpContext.Current.Request.Url.Host + "/TechLadder";
 
    // render the output of the user control to a string, for use by the email message body
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    System.IO.StringWriter sw = new System.IO.StringWriter(sb);
    System.Web.UI.HtmlTextWriter htmltw = new System.Web.UI.HtmlTextWriter(sw);
    cc.RenderControl(htmltw);
    content = sb.ToString();
 
    return content;
}
 
private void SendSupervisorEmail(string email)
{
    try
    {
        MailAddress from = new MailAddress("no-reply@andrew.com");
        MailAddress to = new MailAddress(email);
        MailMessage Message = new MailMessage(from, to);
        Message.IsBodyHtml = true;
        Message.Subject = "System Engineering Technical Ladder";
        string superMsg = getSupervisorEmailContent();
        Message.Body = superMsg;
 
        SmtpClient client = new SmtpClient(ConfigurationManager.AppSettings["Andrew:MailServer"]);
        client.Send(Message);
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Tuesday, July 17, 2007

SAP MDM COM API

For more than a year I’ve been using the SAP MDM (Master Data Management) COM API with .NET 1.1. Getting started was frustrating. There isn’t a lot of code samples out there.
Here is a simple function to get the product record by product ID.

public static XCATCOMLib.ResultSet GetResultSet(int productID, XCATCOMLib.Catalog catalog)
{
XCATCOMLib.Search search = new XCATCOMLib.SearchClass();
XCATCOMLib.ResultSetDefinition productsRsDef = null;

// get references to tables
XCATCOMLib.Tables tables = catalog.Tables;
XCATCOMLib.Table prodTable = tables.Item(PRODUCT_TABLE);

// products
productsRsDef = new XCATCOMLib.ResultSetDefinitionClass();
productsRsDef.Table = prodTable.Name;

//get the column names of the product table
for (int j = 0; j < prodTable.Fields.Count; j++)
{
productsRsDef.Fields.Add(prodTable.Fields.Item(j));
}

XCATCOMLib.TableParameter lp = search.Parameters.NewTableParameter(PRODUCT_TABLE);
lp.RecordIDs.Add(productID);

ResultSet rs = catalog.GetResultSet(search, productsRsDef, prodTable.Fields.Item(0).Name, true, 0);

return rs;
}

Retrieve Microsoft Exchange FreeBusy data

I wanted to show an exchange users calendar for the current day. There is a command you can use with Microsoft Outlook web access. At first I thought I could just call this command, parse the XML and display a table from 8am to 5pm showing out of office, in a meeting, etc..
What I didn’t realize is that you will always get back null unless you run the command on the exchange server. Microsft actually explains that you should use the command to make a web service.

You can also use CDOEX, (Collaboration Data Objects for Exchange), to retrieve the data. Again, this must be run on the exchange server. You’d have to find the cdoex.dll and regsvr32 it locally to add it to Visual Studio. You can find the dll on the exchange server or search the web. That code looks like this:

string freebusy = “EMPTY”;
int Interval = 30;
DateTime dtStartDate = DateTime.Parse(“2/8/2007 1:00:00 AM”);
DateTime dtEndDate = DateTime.Parse(“2/8/2007 11:00:00 PM”);


CDO.Addressee iAddr = new CDO.Addressee();
ActiveDs.ADSystemInfo Info = new ActiveDs.ADSystemInfo();

iAddr.EmailAddress = “example@example.com”;
if (!(iAddr.CheckName(“LDAP://” + Info.DomainDNSName, “”, “”)))
throw new System.Exception(“Error occured!”);

freebusy = iAddr.GetFreeBusy(dtStartDate, dtEndDate, 30, “”, “”, “”, “”);

Change Gridview row color

One way to change the entire row color of a GridView is to do it during RowDataBound(). If a flag returns true from the database I wanted to make that entire row red. Here is how I did that:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView test = (System.Data.DataRowView)e.Row.DataItem;
bool actionPlanExists = SqlConvert.ToBoolean(test.Row[“ActionPlanExists”]);
if (actionPlanExists == true)
{
e.Row.BackColor = System.Drawing.Color.Red;
e.Row.ForeColor = System.Drawing.Color.White;
}
}
}

.NET Localization

Here is code to offer a dropdownlist so visitors can change the language.

– Language –
English
中文版本 - Chinese
Ceština - Czech
Francois - French
Deutsch - German
Italiono - Italian
Español - Spanish
Português - Portuguese

protected void ddlLanguage_SelectedIndexChanged(object sender, EventArgs e)
{
//store the selected language in a cookie
}
protected override void InitializeCulture()
{
string lang = string.Empty;
HttpCookie cookie = System.Web.HttpContext.Current.Request.Cookies[“MyAPP”];

if (cookie != null)
{
try
{
lang = cookie[“Language”];
}
catch
{ }
}

if ((lang != null) && (lang != string.Empty))
{
String selectedLanguage = lang;

if ((selectedLanguage != null) && (selectedLanguage != “”))
{
UICulture = selectedLanguage;
Culture = selectedLanguage;

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(selectedLanguage);
}
base.InitializeCulture();
}
}

MDM Get Attributes

I needed a way to get all the attributes for a repository in MDM. I did that with the MDM COM API like this:


this.catalog = Helper.GetCatalog();


DataTable dt = new DataTable();
dt.Columns.Add(”Name”);
dt.Columns.Add(”ID”);
XCATCOMLib.Attributes allAttributes = new XCATCOMLib.AttributesClass();
allAttributes = catalog.GetAttributes(CATEGORY_TABLE, 0, false);


foreach(XCATCOMLib.Attribute attrib in allAttributes)
{

DataRow row = dt.NewRow();
row[”Name”] = attrib.Name;
row[”ID”] = attrib.ID;
dt.Rows.Add(row);

}

this.dgAttributes.DataSource = dt;

this.dgAttributes.DataBind();

MDM Multiple Languages

MDM has great support for multiple languages. You can login to their GUI client (Data Manager) with your desired language. I found out that when you use the MDM COM API with multiple languages to get images you have to use their enumerations.

You can’t pass in “Original”, you must pass in XCATCOMLib.ImageVariantTypeEnum.xcOriginalType
I also had to get the “Images” tableID. Otherwise the Secondary languages will not retrieve an image.

Here’s a function to get an image:

public static string GetImage(XCATCOMLib.Fields objFields, XCATCOMLib.Catalog catalog, ImageVariantTypeEnum variantType)
{
string imgURL;
System.Object[] imgID = (System.Object[])objFields.Item(”Images”).Value;
int imagesTable = objFields.Item(”Images”).LookupTableID;
int webimgID = int.Parse(imgID.GetValue(0).ToString());

CachedImageInfo imgInfo = catalog.GetCachedImageInfo(imagesTable, webimgID, variantType);
string imageCached = imgInfo.CachedPath.Replace(”\\”,”/”);
imgURL = ConfigurationSettings.AppSettings[”ImagesCacheFolder”] + “/” + imageCached;

return imgURL;
}