Wednesday, December 11, 2013

Paging with a ListView instead of a Repeater

I came across a task which required the functionality of a repeater (the ability to bind data and have it display in an HTML item template), but also the ability to page through the data (much like a GridView). There were some solutions out there, which required a lot of customization and involved too much time to make it worthwhile.

The ListView control however allows the display of bound data in an HTML template as well as other features such as: sorting, data editing, data insertions, and data deletions.

The following code is the basic structure for the ListView. The placeholder is where each item template will be placed (which is handy when you want a div or other HTML element to wrap around the data items). You can then add the DataPager, which allows for the ListView paging. You will also need the page properties changing event to ensure the paging works seamlessly.

Monday, December 2, 2013

ASP GridView HyperLink without Code Behind

The following code snippet allows for a hyperlink to be built using the GridView's data source, along with a specified URL format.

<asp:HyperLinkField HeaderText="View Newsletter" DataNavigateUrlFields="Newsletter_Edition" DataNavigateUrlFormatString="/About/Pages/Newsletter.aspx?Edition={0}" Text="View" />
It would appear in the GridViews full source, like follows:
 <asp:GridView ID="gridArchive" runat="server" AutoGenerateColumns="False" Width="800px" CssClass="newsletter">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Issue_x0020_Date" HeaderText="Date Published" />
<asp:BoundField DataField="Edition" HeaderText="Edition" />
<asp:HyperLinkField HeaderText="View Newsletter" DataNavigateUrlFields="Edition" DataNavigateUrlFormatString="/About/Pages/Newsletter.aspx?Edition={0}" Text="View" />
</Columns>
</asp:GridView>

Tuesday, November 5, 2013

jQuery Fancybox: do a postback on parent page when closed

If you need the parent page to perform a postback when a child jQuery fancybox is closed, the following solution has worked for me.

Include the following function on the page (or refrenced via external file):
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
Then on the fancybox jQuery declaration, include the following:
$(".fancybox").fancybox({
'autoScale': false,
'width': 800,
'height': 800,
'type': 'iframe',
'scrolling': 'no',
'showCloseButton': true,
afterClose: function () {
__doPostBack();
}
});
 

Tuesday, October 29, 2013

Visual Studio data access does not pickup return columns

I have noticed an interesting error with some stored procedures where Entity Framework or C# DataSets are unable to detect what the return data type will be. It appears to be due to the fact that when the stored procedure is added, the parameters are sent in as nulls, therefore the procedure won't execute properly and no return is generated.

After some searching I have found that by adding the following line to the start of the stored procedure, Visual Studio will then pickup the correct return type:

IF (1=0) BEGIN SET FMTONLY OFF END
The FMTONLY option is set to off by default, which allows stored procedures to return result sets as normal when they run. When Visual Studio runs a stored procedure for the first time (to get all input/output column names/types) it runs with FMTONLY set to on which basically allows it to parse the procedure for all columns (without actually sending any data in and running the logic). However because the actual logic of the stored procedure is not being run, temp tables and other advanced SQL logic used to return data are not run which means there are no return types being generated (so Visual Studio will not pick up the return columns).

Because FMTONLY is originally set to on, the logical if statement "IF (1=0)" is ignored, and FMTONLY turns itself off. Which means the "IF (1=0) BEGIN SET FMTONLY OFF END" fix is ignored during normal calls to the procedure but executed when Visual Studio and other scrapers access the procedure.

Wednesday, September 25, 2013

C# designer.cs file is not updating correctly

In some cases you may end up with a designer.cs file which is missing control references or still has references to controls which have been removed from the front end display. I have had this happen from time to time and the fix that has generally worked for me is as follows:
Add another ASP control to the front end and save that file. The designer.cs should then fix itself.

Or alternatively:
Edit something on the front end and save that file. The designer.cs should then fix itself.

Thursday, September 5, 2013

Excel VBA - Print all Worksheets in a Workbook

A simple code snippet that can be used to print all Worksheets in an Excel Workbook is as follows:
Sub PrintAllSheets()
    Application.DisplayAlerts = False
         Dim WS_Count As Integer
         Dim I As Integer
         ' Set WS_Count equal to the number of worksheets in the active
         WS_Count = ActiveWorkbook.Worksheets.Count
         For I = 1 To WS_Count
            ActiveWorkbook.Worksheets(I).Select
               
            ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True, _
            IgnorePrintAreas:=False
        End If
    Next I
End Sub

Friday, August 16, 2013

CSS One Image on Top of Another

This is some simple CSS to overlay one image on top of another.
<div style="position: relative; left: 0; top: 0;">
  <img src="a.jpg" style="position: relative; top: 0; left: 0;"/>
  <img src="b.jpg" style="position: absolute; top: XXX; left: XXX;"/>
</div>
a.jpg will be the main image and b.jpg would be the image you want over top.  You can position the overlay image using the top and left attributes.

Thursday, August 8, 2013

C# Class Within Another Class

Sometimes you need a parent class in C# to contain another class, the simple method for doing this is as follows:
class ParentClass
{
public string Name { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public ChildClass ChildClass;
}
class ChildClass
{
public string MemberNumber { get; set; }
public string Subscription { get; set; }
}

C# Working With JSON Web Service

string serviceUrl = ConfigurationManager.AppSettings["serviceUrl"].ToString();
var httpWebRequest = (HttpWebRequest)WebRequest.Create(serviceUrl );
httpWebRequest.Method = WebRequestMethods.Http.Post;
httpWebRequest.Accept = "application/json";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "auth_token=" + token; // Not actually JSON format (effectively a simple query string)
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd(); // data in JSON format
// Parse the JSON into custom object
 JavaScriptSerializer serializer1 = new JavaScriptSerializer();
customClass obje = serializer1.Deserialize<customClass>(result); 
}

}

In the above example the web service outputs JSON, but takes data in via query string. The code could be adapted to send the data in as JSON as well.


Monday, August 5, 2013

C# DataTable Copy vs Clone

C# DataTable Copy Method
Creates a new copy of the DataTable including structure and data.

C# DataTable Clone Method
Creates a new copy of the DataTable structure, but does not copy the data.

Convert String to XML

A simple way to convert a string to XML is as follows:
string xmlContent = "<ViewFields><FieldRef Name=\"ID\" /><FieldRef Name=\"Title\" /></ViewFields>";
XmlDocument nd = new XmlDocument();
nd.LoadXml(xmlContent);
XmlNode viewFields = nd.DocumentElement;
In this example we drill down deeper to get an XmlNode (used for querying SP lists).

Hexadecimal value 0x13, is an invalid character

Using the SharePoint 2007 Lists web service, the following error was returned when the GetListItems method was returning XML containing the data.
 hexadecimal value 0x13, is an invalid character. Line XXX, position XXX.
Looking into the error, it appeared a bad character was being returned. I was eventually able to trace the exact record causing the error and it was due to double and triple exclamation marks (which appear to have been copied from Microsoft Word into the text editor).

The request failed with HTTP status 403: Forbidden

When connecting to a SharePoint 2007 lists service the following error message is encountered:
The request failed with HTTP status 403: Forbidden
 The server is using Forms Based Authentication and an auth cookie was generated but never assigned to the service.
newListProxy.CookieContainer = cookieContainer; // Assign Cookie

Working with XmlWriter in C#

The following XML code needed to be generated for the SharePoint 2007 Lists service.
<Batch OnError="Continue" ListVersion="1" 
ViewName="270C0508-A54F-4387-8AD0-49686D685EB2">
   <Method ID="1" Cmd="Delete">
      <Field Name='ID'>2</Field>
   </Method>
   <Method ID="2" Cmd="Delete">
      <Field Name='ID'>8</Field>
   </Method>
</Batch>
 It can be done using XmlWriter in C#
using (XmlWriter writer = XmlWriter.Create("test.xml"))
{
writer.WriteStartDocument();
writer.WriteStartElement(
"Batch");
writer.WriteAttributeString("OnError", "Continue");
writer.WriteAttributeString("ListVersion", "1");
writer.WriteStartElement("Method");
writer.WriteAttributeString("ID", "1");
writer.WriteAttributeString("Cmd", "New");
writer.WriteStartElement("Field");
writer.WriteAttributeString("Name", "ID");
writer.WriteString("Item ID");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
}

Thursday, August 1, 2013

Add a Web Reference to a Console Application

For non web projects in c# there is an extra step to add a web reference. Right click on 'References' and then 'Add Service Reference'. A dialog box should appear, at the bottom left hand corner click the 'Advanced' button. Another dialog box will appear, click the 'Add Web Reference' button in the bottom left hand corner. Now you can add your web reference.

Tuesday, July 30, 2013

c# Is Numeric Function

Just a quick function which I found online some time ago.

public
static System.Boolean IsNumeric(System.Object Expression)
{
if (Expression == null || Expression is DateTime)
return false;
if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
return true;
try
{
if (Expression is string)
Double.Parse(Expression as string);
else
Double.Parse(Expression.ToString());
return true;
}
catch { } // just dismiss errors but return false
return false;
}

Monday, July 29, 2013

SharePoint 2007 Lists Web Service

SharePoint 2007 offers a web service that can be used to query the lists/libraries in your SharePoint site. The service is available at http://server/adm/_vti_bin/lists.asmx and is enabled by default. Below is an image containing the various methods available for use.

Use of the service requires authentication; via Active Directory or in this example using forms based authentication. First create a web reference to the URL above (customize it for your server) and call the reference 'ListProxy'.

ListProxy.Lists newListProxy = new AdvertReport.Generate.ListProxy.Lists();
Here is the code to authenticate with FBA:
protected bool AuthenticateFBAClaims()
{
string userName = ConfigurationSettings.AppSettings["SharePointUser"].ToString();
string password = ConfigurationSettings.AppSettings["SharePointPassword"].ToString();
string server = ConfigurationSettings.AppSettings["SharePointServer"].ToString();

Authentication spAuthentication = new Authentication();
spAuthentication.Url = server + "_vti_bin/Authentication.asmx";
spAuthentication.CookieContainer = new CookieContainer();
LoginResult loginResult = spAuthentication.Login(userName, password);
authCookie = new Cookie();
if (loginResult.ErrorCode == LoginErrorCode.NoError)
{
CookieCollection cookies = spAuthentication.CookieContainer.GetCookies(new Uri(spAuthentication.Url));
authCookie = cookies[loginResult.CookieName];
cookieContainer = new CookieContainer();
cookieContainer.Add(authCookie);
return true;
}
else
return false;
}
}
Now a list can be queried (lists, views and other SharePoint objects are referenced by their GUIDs which can be found using SharePoint Manager 2007).
newListProxy.CookieContainer = cookieContainer;

XmlDocument xmlDoc = new System.Xml.XmlDocument();
XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
ndQuery.InnerXml = CAML
XmlNode ndListItems = newListProxy.GetListItems(listGuid, viewGuid, ndQuery, null, null, null, null);
The XML returned will be in SharePoint format (which can be difficult to work with). Below is a function I found online which converts SP XML to regular XML:
// Convert SP XML to Regular XML
public string ConvertZRowToRegularXml(string zRowData)
{
string xsltFromZRowToXml =
"<xsl:stylesheet version=\"1.0\" " +
"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" " +
"xmlns:s=\"uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882\" " +
"xmlns:z=\"#RowsetSchema\">" +
"<s:Schema id=\"RowsetSchema\"/>" +
"<xsl:output method=\"xml\" omit-xml-declaration=\"yes\" />" +
"<xsl:template match=\"/\">" +
"<xsl:text disable-output-escaping=\"yes\">&lt;rows&gt;</xsl:text>" +
"<xsl:apply-templates select=\"//z:row\"/>" +
"<xsl:text disable-output-escaping=\"yes\">&lt;/rows&gt;</xsl:text>" +
"</xsl:template>" +
"<xsl:template match=\"z:row\">" +
"<xsl:text disable-output-escaping=\"yes\">&lt;row&gt;</xsl:text>" +
"<xsl:apply-templates select=\"@*\"/>" +
"<xsl:text disable-output-escaping=\"yes\">&lt;/row&gt;</xsl:text>" +
"</xsl:template>" +
"<xsl:template match=\"@*\">" +
"<xsl:text disable-output-escaping=\"yes\">&lt;</xsl:text>" +
"<xsl:value-of select=\"substring-after(name(), 'ows_')\"/>" +
"<xsl:text disable-output-escaping=\"yes\">&gt;</xsl:text>" +
"<xsl:value-of select=\".\"/>" +
"<xsl:text disable-output-escaping=\"yes\">&lt;/</xsl:text>" +
"<xsl:value-of select=\"substring-after(name(), 'ows_')\"/>" +
"<xsl:text disable-output-escaping=\"yes\">&gt;</xsl:text>" +
"</xsl:template>" +
"</xsl:stylesheet>";

XslCompiledTransform transform = new XslCompiledTransform();
XmlDocument tidyXsl = new XmlDocument();
try
{
//Transformer
tidyXsl.LoadXml(xsltFromZRowToXml);
transform.Load(tidyXsl);
//output (result) writers
using (System.IO.StringWriter sw = new System.IO.StringWriter())
{
using (XmlTextWriter tw = new XmlTextWriter(sw))
{
//Source (input) readers
using (System.IO.StringReader srZRow = new System.IO.StringReader(zRowData))
{
using (XmlTextReader xtrZRow = new XmlTextReader(srZRow))
{
//Transform
transform.Transform(xtrZRow, null, tw);
return sw.ToString();
}
}
}
}
}
catch(Exception ex)
{
ErrorLog(ex.ToString());
return null;
}
}
Now you can convert the regular XML into a DataSet object:
DataSet ds = new DataSet();
using (System.IO.StringReader sr = new System.IO.StringReader(cleaned)) // Convert XML to DataSet
{
     ds.ReadXml(sr,
    XmlReadMode.Auto);
}

URL Redirection

Two common methods I use for programatically redifrecting the user (in C#) are as follows.

Instant Redirection:
Response.Redirect("http://google.com");
Response.Redirect("http://google.com", false);
The second parameter is EndResponse and indicates whether execution of the current page should terminate.

Delayed Redirection:
Response.AddHeader("REFRESH", "5;URL=http://google.com");

Tuesday, July 23, 2013

Error: Could not find default endpoint element

Could not find default endpoint element that references contract 'Service.Name' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
The Endpoint for the service is missing from the web.config file. The endpoint element should be added under the client parent element in the web.config file. An example would be:

<endpoint address="http://prodcrmservices:8080/Service.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService" contract="CRM.IService" name="BasicHttpBinding_IService" />

SharePoint 2007 Easy Method to Generate CAML Queries

CAML is an XML based language which can be used to query SharePoint lists and libraries. Being XML based it is not the easiest language to write queries in, and business rules/logic can make for some complex statements.
However there is a simple method for generating the CAML.
  1. Create a view on the list/library you wish to query that will display the result set you want returned.
  2. Load up SharePoint Manager 2007 on the SharePoint server.
  3. Using the tree view on the side of SP Manager find the list/library you are querying (under the correct web) and expand the available views.
  4. Click on the relevant view, the right hand window will show the various properties. The Query property will contain the CAML query for that view.

Monday, July 22, 2013

DateTime country format

In cases when you need to work with a DateTime value in a particular country format (for example US or Australian) you can use CultureInfo to achieve this.
CultureInfo culture = new CultureInfo("en-AU");
DateTime reportDate = DateTime.Parse(txtDate.Text, culture);
The example above reads the DateTime variable in using the Australian format (dd/mm/yyyy). It comes in useful if the control is set to display US format for example.

SharePoint 2007 view which web parts are used on a given page

A useful tip for finding which web parts are used on a given page (without checking the page out and editing) is as follows.
Add contents=1 to the URL querystring for the page. For example, if your page URL is http://test.com/page.aspx you would then visit http://test.com/page.aspx?contents=1 to be given a listing of the web parts used on that page.

SharePoint 2007 Command Line Deploy

These are the steps for deploying a WSP solution to SharePoint 2007 using the STSADM command line tool.
For Redeployments If the soltution has been deployed in the past, it will need to be retracted before it can be deployed again. Follow these steps before the deployment.
stsadm -o deactivatefeature -name SolutionName -url http://server
stsadm -o retractsolution -name SolutionName.wsp -immediate -url http://server
stsadm -o execadmsvcjobs
stsadm -o deletesolution -name SolutionName.wsp
Deploying the Solution For new deployments (or redeployments after retracting the solution), follow these steps.
stsadm -o addsolution -filename SolutionName.wsp
stsadm -o deploysolution -name SolutionName.wsp -allowgacdeployment -immediate -url http://server
stsadm -o execadmsvcjobs
stsadm -o activatefeature -name SolutionName -url http://server
Please note: Some commands (such as execadmsvcjobs or activatefeature) may take longer than others to complete.

Dynamic Web Reference URLs

I inherited a number of user controls which had hard coded switches for a WCF service (live and test versions of the same service). Testing became frustrating, as code would need to be commented/uncommented in many different locations. There was also the risk of having the live serice in use on the test environment and the test service in use in the live environment. The solution was to add the URLs for the live/test references, as well as a bool for test mode into the web.config file. A switch was then used to decide which mode was active (live or test) and using the 'Url' property of the client the correct reference URL would be used.
MyClient client = new MyClient();
client.Url = "http://service.url";
The live web reference still needed to be added to the solution and a reference to it in the relevant files to ensure the correct classes/methods were available. However in this case the live/test services were identical.