I just finished writing my first production WCF application, which worked very well until I deployed it to our production environment.  All of a sudden none of the WCF calls would work, and I would get a JavaScript "TestService is not defined" error.  When I look inside the JS service reference (in debug mode), I got the following error:

Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https]

So apparently my WCF service registered itself as HTTPS (since it is over SSL), but my binding was only configured for HTTP.  The solution is to define a custom binding inside your Web.Config file and set the security mode to "Transport".  Then you just need to use the bindingConfiguration property inside your endpoint definition to point to your custom binding.  The entire HTTPS-enabled system.serviceModel section is below:

<system.serviceModel>
<behaviors>    
 <endpointBehaviors>
  <behavior name="TestServiceAspNetAjaxBehavior">
   <enableWebScript />
  </behavior>
 </endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
 <service name="TestService">
  <endpoint address="" behaviorConfiguration="TestServiceAspNetAjaxBehavior"
   binding="webHttpBinding" bindingConfiguration="webBinding" contract="TestService" />
 </service>
</services>
 <bindings>
   <webHttpBinding>
     <binding name="webBinding">
       <security mode="Transport">
       </security>
     </binding>
   </webHttpBinding>
 </bindings>
</system.serviceModel>

Hopefully this will help someone who has the same problem.

I recently ran into a scenario where I needed to have a submit button exclusively run some client code, which is pretty common and usually handled by having some DOM element call an onclick method that does the work.  However, there was quite a bit of validation that needed to be done and I did not want to have to rewrite the logic that the built in ASP.NET Validators provide.  My solution was to make the form as if I was going to do a full postback, including adding validation to many different controls.  Then I intercepted the postback by calling my custom JavaScript validation/action method and then returning false inside the OnClientClick property of the submitting button (which suppresses the postback, and also the validation).  With the use of Firebug (an essential web development tool for Firefox) I was able to drill into the WebForm__DoPostBackWithOptions() method (included in the WebResource.axd JavaScript include) that ASP.NET uses.  The first few lines are as follows:

var validationResult = true;
 if (options.validation) {
 if (typeof(Page_ClientValidate) == 'function') {
 validationResult = Page_ClientValidate(options.validationGroup);
 }
 }

From there you can see that all of the work is done inside the Page_ClientValidate("ValGroup") function, which you can call from your own code to get the best validation without the postback.  What follows is a quick example of how you would use this in practice:

ASP.NET

<asp:TextBox runat="server" ID="tbHours" Width="50px"></asp:TextBox>
<asp:RequiredFieldValidator ID="rvalAddHours" runat="server" ControlToValidate="tbHours" ValidationGroup="AddEntry" ErrorMessage="* Hours Required" Display="Dynamic"></asp:RequiredFieldValidator>
<asp:RangeValidator ID="rgValAddHours" runat="server" ControlToValidate="tbHours" ValidationGroup="AddEntry" ErrorMessage="* Hours Must Be 0-24" Display="Dynamic" Type="Double" MinimumValue="0" MaximumValue="24"></asp:RangeValidator>
<asp:Button ID="btnAddEntry" runat="server" OnClientClick="ValidateAndAddNewEntry(); return false;" CausesValidation="true" ValidationGroup="AddEntry" Text="Create" />

JavaScript

function ValidateAndAddNewEntry()
{
    var res = Page_ClientValidate("AddEntry");
    
    if ( res == true )
    {
        //Do work
    }
}

Happy Coding!

Sending Email using Exchange 2007 Web Services (EWS) is a little trickier than I first anticipated (read: counterintuitive), since it uses the service.CreateItem() method call instead of the service.SendItem().  The basic idea is to formulate the email message as a CreateItemType with a MessageType assigned to the Item property, with the MessageDisposition set to "MessageDispositionType.SendAndSaveCopy."  The following code shows an example of a library method that can send a basic email message with no attachments from a sender to a single recipient (it should be fairly easy to extrapolate multiple recipients, cc's & bcc's from there).

The first step with any EWS call is to set up your Exchange Service Binding:

ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Credentials = new NetworkCredential(config.UserName, config.Password, config.Domain);
 
esb.Url = config.ServerURL;

Next, create the root MessageType that will serve as your email message:

MessageType emailMessage = new MessageType();

Now you can add the from/sender as a SingleRecipientType (there can't be multiple senders), and add the ToRecipients as an array of EmailAddressTypes.  I'll also show the body and subject code since it is relatively straightforward.

//Add the sender/recipient to the email message
emailMessage.ToRecipients = new EmailAddressType[1];
emailMessage.ToRecipients[0] = new EmailAddressType();
emailMessage.ToRecipients[0].EmailAddress = "recipient@email.com"; //Currently there is only one recipient
 
emailMessage.From = new SingleRecipientType();  //set up a single sender
emailMessage.From.Item = new EmailAddressType();
emailMessage.From.Item.EmailAddress = "sender@email.com";
 
emailMessage.Subject = "Subject Goes Here";
 
emailMessage.Body = new BodyType();
emailMessage.Body.BodyType1 = BodyTypeType.Text; //specify HTML or plain Text
emailMessage.Body.Value = "Body Goes Here";

The next step is to place the email message inside of a CreateItemType object.

CreateItemType emailToSave = new CreateItemType();
emailToSave.Items = new NonEmptyArrayOfAllItemsType();
emailToSave.Items.Items = new ItemType[1];
emailToSave.Items.Items[0] = emailMessage;
emailToSave.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
emailToSave.MessageDispositionSpecified = true;

Finally, you call the CreateItem() method to create the item and send it off.  I'll usually place this part in a try/catch block, and then return the ResponseCode (inside of the returned ResponseMessageType) so that it can be inspected for success.

CreateItemResponseType response = esb.CreateItem(emailToSave);
 
// Get the response messages.
ResponseMessageType[] rmta =  response.ResponseMessages.Items;

Regardless of the complexities, it sure beats WebDAV!

I've run across a few situations in which I wanted to animate a certain row in a GridView as a result of some client action.  The reason that this is a little tricky is that the AJAX Control Toolkit's Animation Extender needs to act on a certain Target Control (identified of course by the TargetControlID) and you can't point the target control as a specific grid view row (not that you would even want to).

Both methods I will discuss use the same actual animation code -- they just differ in the way in which the animation is called.  I'll begin with the common animation code, which flashes the row with a color change animation (basically a fading highlight).

function animateRow(affectedRow)
{
 //first save the existing row color so you can restore it after the animation is completed
 //you may have to do some post-processing to make sure the affectedRowColor is a hex value like #FFFFFF
 var affectedRowColor = affectedRow.style.backgroundColor;
 animation = new AjaxControlToolkit.Animation.ColorAnimation(affectedRow, 2, 32, "style", "backgroundColor", "#ffff99", affectedRowColor);
 animation.play();
} 

Basically the above code uses the AjaxControlToolkit Animation API to create a ColorAnimation that acts on the affected row, which will cause the entire row to highlight and then fade back to its original color.

The quick method for getting access to the affected row can be used when an element of that row initiates the animation (for example, click on an update button flashes the row that it is contained in).  The code would look something like this:

<asp:TemplateField HeaderText="Highlight My Row"> 
 <ItemTemplate> 
 <input type="button" value="Click Me" onclick="animateRow(this.parentNode.parentNode);" /> 
 </ItemTemplate> 
</asp:TemplateField> 

The onclick event of this template field button calls the above animateRow function and passes it's grandparent node (this.parentNode.parentNode).  Since the DOM tree has the element inside a <td/> which is inside a <tr/>, we know that the element's grandparent is the row to animate.

The second method involves giving each row a unique identifier during the handling of the rowCreated event.  The details will change depending on your implementation, but lets assume that you are using a GridView with a bound ID property (which is also a datakey).  Then you need to handle the rowCreated event and add an "id" attribute to each row:

protected void gv_RowCreated(object sender, GridViewRowEventArgs e) 
 { 
 GridView gview = (GridView)sender; 
 e.Row.Attributes.Add("id", gview.DataKeys[e.Row.RowIndex]["id"].ToString()); 
 } 

This will allow you to dynamically update any row by executing the following javascript:

var id = "idhere"; 
var affectedRow = $get(id); 
 
animateRow(affectedRow); 

With a few modifications you can get some pretty dynamic per-row animations while letting the AJAX Control Toolkit do all the heavy lifting.  Enjoy!

The ASP.NET AJAX Control Toolkit's Calendar (Click Here To See The CalendarExtender Control In Action) is a very nice control that allows you implement a client side dynamic calendar for date-picking functionality. One interesting feature is the ability to change the calendar from the default "days" mode (shows the days in one month) to "months" mode (showing all of the months in the current year) by clicking on the calendar title. Another click on the title will change the calendar into "years" mode, which shows 12 years at a time.

One feature that would be nice is the ability to start the calendar control in any of the desired modes ("days", "months", or "years") depending on the type of interaction with the calendar that is most appropriate. For example, a current project of mine requires entering employee hire dates -- which are almost always at least a few years old.

The following is some simple code that allows you to get the desired functionality (in this case, we switch to the "years" mode) by handling the Calendar's OnClientShown event.

Step 0 -- The initial Calendar control hooked up to a TextBox

<asp:TextBox ID="txtTitleLength" runat="server"></asp:TextBox>

<AjaxControlToolkit:CalendarExtender ID="calTitleLength" runat="server"

TargetControlID="txtTitleLength">

</AjaxControlToolkit:CalendarExtender>

 

Step 1 -- Add a callback to the OnClientShown event (here: "calendarShown")

<asp:TextBox ID="txtTitleLength" runat="server"></asp:TextBox>

<AjaxControlToolkit:CalendarExtender ID="calTitleLength" runat="server"

TargetControlID="txtTitleLength"

OnClientShown="calendarShown">

</AjaxControlToolkit:CalendarExtender>

Step 2 — Handle the OnClientShown event (which takes 2 parameters: "sender, e") and then call the calendar control’s _switchMode() method

function calendarShown(sender, e) { sender._switchMode("years"); }


That’s all there is to it! One note: you must call the switchMode() method in the OnClientShown event and not the OnClientShowing event for the effect to work properly.

I can across a problem today where I had to attach a PDF file that is stored on a network share to an outgoing email using ASP.NET 2.0. This is pretty simple to do, except in my case the PDF filename on the share has an obfuscated name while its original name (file.pdf) is stored in a database lookup table. Looking at the System.Net.Mail.Attachment constructors, you'll see that three take a string filename and three take a System.IO.Stream object to represent the file. The string filename constructors do not possess the ability (as far as I could see) to give the attached file a "friendly name", although one of the Stream constructors does. So what I ended up doing was opening the file with a non-locking FileStream object and then passing it to the mail attachment object, careful to close the stream when I was done. Pretty simple, but I couldn't find any sources using this method so I thought I'd write it down here (minus error handling code for clarity):

System.Net.Mail.MailMessage message =new System.Net.Mail.MailMessage("from@from.com", "to@to.com", "Subject", "My attachment has a friendly name");

//Open the filestream with non-locking read permission

System.IO.FileStream fileStream = new System.IO.FileStream("fileSystemName", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

message.Attachments.Add(new System.Net.Mail.Attachment(fileStream, "friendlyName.pdf"));

fileStream.Close();

I recently ran into a situation where I wanted to render the contents of a user control either directly to the current HTML stream or to a file format like MS Word. Fortunately .NET has the 'LoadControl' function that takes the virtual path of a User Control and returns a Control object. In order to get the rendered output of a user control into an HTML32TextWriter, you can use the following code:

Control report;
 
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
Html32TextWriter hw = new Html32TextWriter(sw);
 
report = LoadControl("WebUserControl.ascx");
report.RenderControl(hw);

One word of caution: When loading a Web User Control through the LoadControl() method, the normal page lifecycle events, such as Page_Init and Page_Load, are not called. To make up for this deficiency, you can cast the returned Control object to the User Control type and call any required methods directly from the object reference before rendering the control. For example, I created an IReportUserControl interface that defines a LoadReport() method, and which all report-type Web User Controls derive from. Then I can simply insert the following code in order to run the proper initialization logic:

report = LoadControl("WebUserControl.ascx"); 
 
((IReportUserControl)report).LoadReport(); //Initialize the control 
 
report.RenderControl(hw);

Exporting a SQL Server Reporting Services 2005 (SSRS) Report Directly to PDF/Excel is a handy way of generating high quality reports without being stuck to using the ReportViewer interface. Sometimes the ReportViewer interface is an unnecessary step, but other times the ReportViewer won't render correctly even though the underlying report is correct. This is especially true when your audience might use Firefox or Safari (or anything other than IE), since the ReportViewer control almost never outputs a readable report. Of course it would be nice to just have a button on your page that generates a PDF or Excel file in any browser, and uses a SSRS back-end to do all of the report creating and heavy lifting.

The following code will show how to export such a report, including the passing of an arbitrary number of custom parameters. Note that the identity of the application pool that your website runs under will need to have at least "browser" access to the folder containing the report you want to display. This is usually pretty simple if both the IIS and SSRS server are within the same domain, but it might be tricky if this is not the case.

Microsoft.Reporting.WebForms.ReportViewer rview = new Microsoft.Reporting.WebForms.ReportViewer();
//Web Address of your report server (ex: http://rserver/reportserver)
 
rview.ServerReport.ReportServerUrl = new Uri(WebConfigurationManager.AppSettings[”ReportServer”]);
 
System.Collections.Generic.List<Microsoft.Reporting.WebForms.ReportParameter> paramList = new System.Collections.Generic.List<Microsoft.Reporting.WebForms.ReportParameter>();
 
paramList.Add(new Microsoft.Reporting.WebForms.ReportParameter(”Param1″, “Value1″));
paramList.Add(new Microsoft.Reporting.WebForms.ReportParameter(”Param2″, “Value2″));
 
rview.ServerReport.ReportPath = “/ReportFolder/ReportName”;
rview.ServerReport.SetParameters(paramList);
 
string mimeType, encoding, extension, deviceInfo;
string[] streamids;
Microsoft.Reporting.WebForms.Warning[] warnings;
string format = “PDF”; //Desired format goes here (PDF, Excel, or Image)
 
deviceInfo =
“<DeviceInfo>” +
“<SimplePageHeaders>True</SimplePageHeaders>” +
“</DeviceInfo>”;
 
byte[] bytes = rview.ServerReport.Render(format, deviceInfo, out mimeType, out encoding, out extension, out streamids, out warnings);
 
Response.Clear();
 
if (format == “PDF”)
{
Response.ContentType = “application/pdf”;
Response.AddHeader(”Content-disposition”, “filename=output.pdf”);
}
else if (format == “Excel”)
{
Response.ContentType = “application/excel”;
Response.AddHeader(”Content-disposition”, “filename=output.xls”);
}
 
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.Flush();
Response.Close();

One potential issue that you might run into upon deploying your project is that your application server may not have the ReportViewer DLLs that are needed. You have two options in this case. The first is to copy the three Microsoft.ReportViewer.*.dll's (ReportViewer.Common.dll, ReportViewer.ProcessingObjectModel.dll, and ReportViewer.WebForms.dll) from your development computer into the BIN folder of your application server (or into the GAC). The second option (though I have not verified it), is to install the SSRS redistributable on the application server (http://www.microsoft.com/downloads/details.aspx?familyid=8a166cac-758d-45c8-b637-dd7726e61367&displaylang=en).

Check out http://www.microsoft.com/sql/technologies/reporting/default.mspx for good SSRS resources, including some nice learning tools and report packs.

When I was converting untyped data values from a SQL database into a custom Business class, I realized that I have to take a special precaution when casting possibly null values. If you try to cast DBNull to some type, you will get an InvalidCastException. When thinking about a solution, I remembered the as operator and decided to do some investigating. Consider the following example:

object objstr = DBNull.Value; 
string str1 = (string)objstr; //Cast throws an Exception 
string str2 = objstr as string; //No exception is thrown, and str2 == null

The as operator lends very well to using the ?? for writing compact code. Here's a little syntactic sugar:

if ( objstr == DBNull.Value )
{
 strResult = "Default";
}
else
{
 strResult = (string)objstr;
}
 
//Is equivalent to
 
strResult = objstr as string ?? "Default";

So it turns out that the as operator is just like the cast operator except that it yields null on conversion failure instead of throwing an exception. Looking at a MSDN C# Programmer's Reference page http://msdn2.microsoft.com/en-us/library/cscsdfbt(vs.71).aspx confirmed this, and even offered up the following explanation.

expression as type
 
//is equivalent to
 
expression is type ? (type)expression : (type)null

Creating a Custom Code Snippet is pretty easy to do -- you just fire up your favorite text editor, write some XML, and save the results in a *.snippet file. If you use Visual Studio as your text editor, you can even get some XML Intellisense, which is always nice. I am going to create a code snippet called rw.snippet, which will simply expand to Response.Write();, and leave your cursor inside the parenthesis (something I use far too often, along with Trace.Write(), for debugging).

To get started, create an empty text file in Notepad (or similar), and add the following lines to indicate that you want to write a custom code snippet.

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
</CodeSnippet>
</CodeSnippets>

Now save the file as rw.snippet (I would recommend saving it in your Visual Studio 2005\Code Snippets\[Language]\My Code Snippets folder) and close out of NotePad. Open the file in Visual Studio (note: since the file has the *.snippet extension, it should now be registered to open with Visual Studio by default). You should see the XML scheema information that you copied earlier, and you should get some next text highlighting as well.

Inside the <CodeSnippet> tag, you can add header information inside a <Header> tag, including a Title, Shortcut (the keyboard shortcut to be used), Description and more. You can use Intellisense to see all the possibilities. For now, I'll add the following information:

<Header>
<Title>rw</Title>
<Shortcut>rw</Shortcut>
<Description>Code snippet for generating Response.Write</Description>
<Author>Scott K</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>

Next, you create the <Snippet> tag where the actual implementation will take place. Inside the snippet tag, you can define variables (literals/objects) to be filled in later (called Declarations) as well as the <Code> section containing your actual snippet content. The <Code> tag itself can define a few properties, like the declaration 'delimiter', 'kind' (to filter snippets based on code location), and 'language' (mainly helpful for organization) options. Inside the <Code> tag, you will create a <![CDATA[]]> section which will hold the snippet body as a plain string. The Snippet section for my Response.Write() snippet will look like the following:

<Snippet>
<Code Language="csharp">
<![CDATA[Response.Write($end$);]]>
</Code>
</Snippet>

Here, 'end' is a built-in declaration for the position the cursor will end up after expanding the snippet, and since we didn't change the delimiter is it defaulted to $. So the complete code for the rw.snippet file is:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>rw</Title>
<Shortcut>rw</Shortcut>
<Description>Code snippet for Response.Write</Description>
<Author>Scott K</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language="csharp">
<![CDATA[Response.Write($end$);]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Once you have saved your file, inside Visual Studio click on Tools->Code Snippets Manager. Now choose the Import Option, navigate to your file save location and choose rw.snippet Choose where to put the snippet (I chose Visual C#) and click OK. Thats it! Now when you are typing in a normal coding environment, type rw and you will see the code snippet paper icon appear with rw in Intellisense. Press tab to expand out this snippet, and you will get Response.Write(); with your cursor ready for action inside the parenthesis.

Now the you have a working snippet, you may want to create a more complex snippet with custom declarations. All you have to do is add declarations to the <Snippet> tag and give them IDs, and then reference those IDs inside your CDATA[] block. For example, I will create a variable name declaration called var and then add it to the rw snippet I just created (disclaimer: this is just for demonstration purposes, obviously the following code would not be very helpful) which will print out a string. The declarations section would look like this:

<Declarations>
<Literal>
<ID>var</ID>
<ToolTip>Name for the string variable</ToolTip>
<Default>var</Default>
</Literal>
</Declarations>

And then the new CDATA[] section would look like this:

<![CDATA[string $var$ = "Hello World";
Response.Write($var$);
$end$]]>

When you expand that out as a code snippet and fill in the var name, you'll get a code block like this:

string helloString = "Hello World";
Response.Write(helloString);

That's really all there is to it -- for more advanced snippets you can look at the built in ones that Microsoft wrote, but this tutorial should give you all the tools you need to write some pretty advanced and time saving snippets.

More Posts Next page »