Wednesday, January 14, 2009
Old Skool VB Trickery
I used the following combination of the InStr and Mid functions to modify values on all rows in Sheet1.
Sub RemoveHashesFromAM()
Dim b
Dim v
Dim lresult As String
For i = 1 To 1124
If InStr(1, Sheet1.Cells(i, 16), ";#") > 0 Then
b = InStr(1, Sheet1.Cells(i, 16), ";#")
b = b + 2
Sheet1.Cells(i, 16) = Mid(Sheet1.Cells(i, 16), b)
End If
Next i
End Sub
And I used the following Replace and Trim functions as necessary
Sheet1.Cells(i, 31) = Replace(Sheet1.Cells(i, 31), ";#", " ")
Sheet1.Cells(i, 31) = Trim(Sheet1.Cells(i, 31))
Thursday, October 23, 2008
Elevation nightmares
"The operation is not valid due to the current state of the object"
Elevation of code is necessary in Sharepoint coding because, depending on the user in context at the time the application code executes, an un-elevated version of the code may or may not work. You need to have the correct rights as the user running the application code at a given point in time in order to have it execute successfully.
Up until now I'd been doing all my elevation like so:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite elevatedSite = new SPSite(siteUrl))
{
using (SPWeb elevatedWeb = elevatedSite.OpenWeb())
{
SPList elevatedList = elevatedWeb.Lists["Tasks"];
if (elevatedList != null)
{
SPListItem elevatedListItem = elevatedList.Items[0];
Console.WriteLine("The task is: " + elevatedListItem["Task"].ToString());
Console.WriteLine("The due date for the task is: " + elevatedListItem["DueDate"].ToString());
Console.WriteLine("The task was created by: " + elevatedListItem["Creator"].ToString());
}
}
}
});
This code block will work flawlessly - the details of the task output to the console.
But the problem comes when I try to update the list item...
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite elevatedSite = new SPSite(siteUrl))
{
using (SPWeb elevatedWeb = elevatedSite.OpenWeb())
{
SPList elevatedList = elevatedWeb.Lists["Tasks"];
if (elevatedList != null)
{
SPListItem elevatedListItem = elevatedList.Items[0];
Console.WriteLine("The task is: " + elevatedListItem["Task"].ToString());
Console.WriteLine("The due date for the task is: " + elevatedListItem["DueDate"].ToString());
Console.WriteLine("The task was created by: " + elevatedListItem["Creator"].ToString());
try
{
elevatedListItem["DueDate"] = DateTime.Now.AddDays(12).ToString();
try
{
elevatedWeb.AllowUnsafeUpdates = true;
elevatedListItem.Update();
}
catch (SPException updateEx)
{
Console.WriteLine("There was an error updating the list item. " + updateEx.ToString());
}
finally
{
elevatedWeb.AllowUnsafeUpdates = false;
}
}
catch (SPException updateFieldValueEx)
{
Console.WriteLine("Error updating field value for column 'DueDate'. " + updateFieldValueEx.ToString());
}
}
}
}
});
The error will occur:
"The operation is not valid due to the current state of the object"
Basically, in short, there appears to be a bit of an issue with updating an item inside an elevated wrapper. My best guess as to the reason this is occurring is that it is due to the fact that elevation of code will not allow for updates to occur because then the update would be occuring as an elevated user and would not contain information on the user in context running the code which is of course used to update the modified by value on a list item, though I have not found any official line to support this theory.
The Solution
The solution is to rejig your code slightly and do your update outside of your elevation wrapper, like so:
// Declare list item, list and web variables outside of elevation block
SPListItem elevatedListItem = null;
SPList elevatedList = null;
SPWeb elevatedWeb = null;
// Elevate to get hold of the list item
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite elevatedSite = new SPSite(siteUrl))
{
elevatedWeb = elevatedSite.OpenWeb();
elevatedList = elevatedWeb.Lists["Tasks"];
if (elevatedList != null)
{
elevatedListItem = elevatedList.Items[0];
}
}
});
// Do the output and update
Console.WriteLine("The task is: " + elevatedListItem["Task"].ToString());
Console.WriteLine("The due date for the task is: " + elevatedListItem["DueDate"].ToString());
Console.WriteLine("The task was created by: " + elevatedListItem["Creator"].ToString());
if (elevatedListItem != null)
{
try
{
elevatedListItem["DueDate"] = DateTime.Now.AddDays(12).ToString();
try
{
elevatedWeb.AllowUnsafeUpdates = true;
elevatedListItem.Update();
}
catch (SPException updateEx)
{
Console.WriteLine("There was an error updating the list item. " + updateEx.ToString());
}
finally
{
elevatedWeb.AllowUnsafeUpdates = false;
}
}
catch (SPException updateFieldValueEx)
{
Console.WriteLine("Error updating field value for column 'DueDate'. " + updateFieldValueEx.ToString());
}
}
That should do it! There should be no more operation is invalid error.
Friday, August 15, 2008
AJAX call within the same page
Example
First set up your code behind like so:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.Services;
namespace PostAuthenticateRequestModule
{
public class SignOut : Page
{
[WebMethod]
public static string GetServerTime()
{
return DateTime.Now.ToString();
}
}
}
And then your ASPX page goes something like this:
Tuesday, February 20, 2007
ASP.NET 2.0 ObjectDataSource Madness
You thought with .NET 2.0 that all your data binding woes had been answered. Oh how very wrong you were, you poor, poor developer (emphasis on poor; these are hard times, what with house prices soaring and whatnot).
It is true to say that you can use an ObjectDataSource in conjunction with a GridView control to present data to the user in a nice tabular format, though you are not likely to achieve this without a) pain b) coffee and c) (in extreme cases) a near-death experience.
Here are some brief and scattered notes on my experiences whilst attempting to use Object Data Sources:
- Update methods can get easily out of synch. There is a hack-around/fix for this - use the ODS 'OnUpdating' method, like so:
//protected void DtypesODS_Updating(object source, ObjectDataSourceMethodEventArgs e)And obviously add a ref to that in your aspx, or initialise the event by overriding OnInit.
{
// Modify input parameters because ODS is too dumb to figure it out.
if (e.InputParameters.Contains("DType"))
e.InputParameters.Remove("DType");
}
[More to come.]
Thursday, February 15, 2007
Using A Class From A Seperate Assembly With An ObjectDataSource
<%@ Register TagPrefix="MyAssembly" Namespace="MyAssembly.Data" Assembly="MyAssembly, Version=1.0.0.1, Culture=neutral, PublicKeyToken=zj1251fcc32b5cg6" %>
Now set the ObjectDataSource's "TypeName" property to the specific class:
TypeName="MyAssembly.Data.MyDataClass"
Now right click on the object data source in design view and select 'Configure Data Source' and you'll see the methods on your class to choose from.
Friday, February 09, 2007
ASP.NET 2.0 - Some Basic Things To Remember
# Bind("MyFieldName")
- When you want to use evaluation, for example a value against a protected method, use:
# IsLead(Eval("Lead"))
Code behind:
protected string IsLead(object val)
{
if (val.ToString() == "True")
return "Yes";
else
return String.Empty;
}
Friday, December 15, 2006
Sharepoint rollup web parts
One of the requirements for the portal I've been working on was to create a rollup webpart of all the Tasks lists across the entire site collection. Using VS.NET, I created the following WebPart-derived class and deployed it to the Sharepoint server.
1 using System;
2 using System.Runtime.InteropServices;
3 using System.Web.UI;
4 using System.Web.UI.WebControls.WebParts;
5 using System.Xml.Serialization;
6
7 using Microsoft.SharePoint;
8 using Microsoft.SharePoint.WebControls;
9 using Microsoft.SharePoint.WebPartPages;
10
11 using System.Xml;
12 using System.Xml.Xsl;
13 using System.IO;
14 using System.Text;
15
16 using System.Data;
17
18 namespace Custom.WebParts
19 {
20 [Guid("9e209402-e946-4070-b869-3faa90a92513")]
21 public class TasksRollUp : System.Web.UI.WebControls.WebParts.WebPart
22 {
23 // Private vars.
24 private string strCulture = "en-GB";
25 private string strUserOrGroup = "Context"; // by default, base the results on the user in context.
26
27 // Checkbox private vars.
28 private bool bStatusNotStarted = true;
29 private bool bStatusInProgress = true;
30 private bool bStatusCompleted = true;
31 private bool bStatusDeferred = true;
32 private bool bStatusWaitingOnSomeoneElse = true;
33
34
35 /// <summary>
36 /// The main method to write to the UI.
37 /// </summary>
38 /// <param name="writer"></param>
39 protected override void Render(HtmlTextWriter writer)
40 {
41 string results = LoadTasks();
42 writer.Write(results);
43 }
44
45 /// <summary>
46 /// Loads 'All My Tasks'.
47 /// </summary>
48 private string LoadTasks()
49 {
50 // Knock up a SPSiteDataQuery object and detail the CAML query.
51 bool applyContextOrGroup = (this.UserOrGroup == "") ? false : true;
52
53 string user = "";
54 if (this.UserOrGroup.ToLower() == "context")
55 user = SPContext.Current.Web.CurrentUser.Name;
56 else
57 user = this.UserOrGroup;
58
59 SPSiteDataQuery q = new SPSiteDataQuery();
60
61 if (!applyContextOrGroup)
62 {
63 q.ViewFields = "<FieldRef Name=\"ID\" /><FieldRef Name=\"Title\" /><FieldRef Name=\"Created\" /><FieldRef Name=\"Body\" />";
64 q.Lists = "<Lists ServerTemplate=\"107\"/>";
65 q.Webs = "<Webs Scope=\"Recursive\"/>";
66 q.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"String\">1</Value></Eq></Where>";
67 }
68 else if (applyContextOrGroup == true && user == "context")
69 {
70 q.ViewFields = "<FieldRef Name=\"ID\" /><FieldRef Name=\"Title\" /><FieldRef Name=\"Created\" /><FieldRef Name=\"Body\" />";
71 q.Lists = "<Lists ServerTemplate=\"107\"/>";
72 q.Webs = "<Webs Scope=\"Recursive\"/>";
73 q.Query = "<Where><And><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">1</Value></Eq><Eq><FieldRef Name=\"AssignedTo\" /><Value Type=\"User\">" + user + "</Value></Eq></And></Where>";
74 }
75 else
76 {//GROUPS.
77 q.ViewFields = "<FieldRef Name=\"ID\" /><FieldRef Name=\"Title\" /><FieldRef Name=\"Created\" /><FieldRef Name=\"Body\" />";
78 q.Lists = "<Lists ServerTemplate=\"107\"/>";
79 q.Webs = "<Webs Scope=\"Recursive\"/>";
80 q.Query = "<Where><Eq><FieldRef Name=\"AssignedTo\" /><Value Type=\"User\">" + user + "</Value></Eq></Where>";
81 }
82
83 DataTable dt = null;
84 SPWeb w = SPContext.Current.Web;
85 // Load ALL 'My' tasks from across ALL sites.
86 dt = w.GetSiteData(q);
87
88 w = null;
89
90 if (dt.Rows.Count == 0)
91 return "No tasks to view on this level.";
92
93 DataSet ds = new DataSet();
94 ds.Tables.Add(dt);
95
96 string xml = ds.GetXml();
97
98 // Format the data.
99 xml = System.Text.RegularExpressions.Regex.Replace(xml, "<", "<");
100 xml = System.Text.RegularExpressions.Regex.Replace(xml, ">", ">");
101
102 // XSL parameter list.
103 XsltArgumentList oArgList = new XsltArgumentList();
104
105 // Site ID is based on SPContext.
106
107 #if DEBUG
108 oArgList.AddParam("SiteId", "", "2352352"); // FOR TEST.
109 #else
110 oArgList.AddParam("SiteId", "", SPContext.Current.Site.ID.ToString());
111 #endif
112 // Set the culture, based on the setting. (Default to site wide culture setting).
113 oArgList.AddParam("Culture", "", this.Culture);
114
115 string outHtml = XslTransform(xml, "/", "Shared Documents", "TaskList.xsl", oArgList);
116 return outHtml;
117 }
118
119 public CustomDocument GetDocument(string fileName, string pathWeb, string listName)
120 {
121 SPSite gSite = null;
122 SPWeb gWeb = null;
123 SPList gList;
124 CustomDocument bdoc = new CustomDocument();
125 try
126 {
127 // If the Path web is passed in then use it to find the list otherwise use current context
128 #if DEBUG
129 //FOR TEST.
130 SPSite s = new SPSite("http://localhost");
131 gSite = s;
132 #else
133 // gSite = SPContext.Current.Site; // Doesn't work. Mais pourquoi?
134 SPSite s = new SPSite("http://localhost");
135 gSite = s;
136 #endif
137 gWeb = gSite.AllWebs[pathWeb];
138 gList = gWeb.Lists[listName];
139
140 foreach (SPListItem item in gList.Items)
141 {
142 if (item.Title.ToLower() == fileName.ToLower())
143 {
144 byte[] xmlfile = item.File.OpenBinary();
145 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
146
147 bdoc.Body = enc.GetString(xmlfile);
148 bdoc.DocumentID = item.UniqueId.ToString();
149 bdoc.list = gList.ID.ToString();
150 //bdoc.CheckedOutTo = item.File.CheckedOutBy.ToString();
151 }
152 }
153 return bdoc;
154 }
155 catch (Exception ex)
156 {
157 bdoc.Body = ex.Message.ToString();
158 return bdoc;
159 }
160 finally
161 {
162
163 if (gSite != null)
164 gSite.Dispose();
165
166 if (gWeb != null)
167 gWeb.Dispose();
168 }
169 }
170
171 /// <summary>
172 /// Perform an XSL transform.
173 /// </summary>
174 /// <param name="xml">The raw XML to use</param>
175 /// <param name="xsl">The XSL document name</param>
176 /// <param name="sharepointPath">The Sharepoint path</param>
177 /// <param name="sharepointList">The Sharepoint list name</param>
178 /// <param name="parameters">A list of XSL parameters</param>
179 /// <returns></returns>
180 public string XslTransform(string xml, string sharepointPath, string sharepointList, string xsl, XsltArgumentList parameters)
181 {
182 // Get the TaskList.xsl file from Sharepoint.
183 CustomDocument oDoc = GetDocument(xsl, sharepointPath, sharepointList);
184
185 TextReader trXSL;
186 trXSL = new StringReader(oDoc.Body);
187
188 // Load up a reader object with the contents of the XSL.
189 XmlReader xrXSL = XmlReader.Create(trXSL);
190
191 StringBuilder sbHTML = new StringBuilder(); // Used for HTML to be returned.
192
193 // Load up an XMLDocument object with the incoming XML...
194 XmlDocument xDoc = new XmlDocument();
195 xDoc.LoadXml(xml);
196
197 // Create an XMLWriter object based on the string builder.
198 XmlWriter xwHTML = XmlWriter.Create(sbHTML);
199
200 // Perform the conversion.
201 XslCompiledTransform xsltTransform = new XslCompiledTransform();
202 xsltTransform.Load(xrXSL);
203
204 try
205 {
206 // Attempt the transform.
207 xsltTransform.Transform(xDoc, parameters, xwHTML);
208 }
209 catch (IOException ioEx)
210 {
211 throw ioEx;
212 }
213 catch (Exception ex)
214 {
215 throw ex;
216 }
217 finally
218 {
219 // Write the results to file.
220 xwHTML.Flush();
221 xwHTML.Close();
222
223 // Clean up.
224
225 trXSL.Close();
226 trXSL.Dispose();
227
228 xrXSL.Close();
229 }
230
231 return sbHTML.ToString();
232 }
233
234
235 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
236 [WebBrowsable(true), Personalizable(true)]
237 [WebDescription("What is the culture? Choose for the time being from two options: the default 'en-GB' or 'en-US'")]
238 [WebDisplayName("Active Culture")]
239 [System.ComponentModel.Category("Custom Settings")]
240 public string Culture
241 {
242 get
243 {
244 return strCulture;
245 }
246 set
247 {
248 strCulture = value;
249 }
250 }
251
252 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
253 [WebBrowsable(true), Personalizable(true)]
254 [WebDescription("Base the task list that is generated on the user in context (type 'Context') - e.g. show only tasks assigned to the user in context, or specify a group name, e.g. 'Administrators'")]
255 [WebDisplayName("Filter by User or Group")]
256 [System.ComponentModel.Category("Custom Settings")]
257 public string UserOrGroup
258 {
259 get
260 {
261 return strUserOrGroup;
262 }
263 set
264 {
265 strUserOrGroup = value;
266 }
267 }
268
269 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
270 [WebBrowsable(true), Personalizable(true)]
271 [WebDescription("Tick to show/hide tasks that have not been started.")]
272 [WebDisplayName("Not started")]
273 [System.ComponentModel.Category("Task Status")]
274 public bool NotStarted
275 {
276 get
277 {
278 return bStatusNotStarted;
279 }
280 set
281 {
282 bStatusNotStarted = value;
283 }
284 }
285
286 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
287 [WebBrowsable(true), Personalizable(true)]
288 [WebDescription("Tick to show/hide tasks that are in progress.")]
289 [WebDisplayName("In progress")]
290 [System.ComponentModel.Category("Task Status")]
291 public bool InProgress
292 {
293 get
294 {
295 return bStatusInProgress;
296 }
297 set
298 {
299 bStatusInProgress = value;
300 }
301 }
302
303 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
304 [WebBrowsable(true), Personalizable(true)]
305 [WebDescription("Tick to show/hide tasks that have been completed.")]
306 [WebDisplayName("Completed")]
307 [System.ComponentModel.Category("Task Status")]
308 public bool Completed
309 {
310 get
311 {
312 return bStatusCompleted;
313 }
314 set
315 {
316 bStatusCompleted = value;
317 }
318 }
319
320 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
321 [WebBrowsable(true), Personalizable(true)]
322 [WebDescription("Tick to show/hide tasks that have been deferred.")]
323 [WebDisplayName("Deferred")]
324 [System.ComponentModel.Category("Task Status")]
325 public bool Deferred
326 {
327 get
328 {
329 return bStatusDeferred;
330 }
331 set
332 {
333 bStatusDeferred = value;
334 }
335 }
336
337 [WebPartStorage(Storage.Shared), System.Xml.Serialization.XmlElement(Namespace = "http://localhost")]
338 [WebBrowsable(true), Personalizable(true)]
339 [WebDescription("Tick to show/hide tasks that are waiting on someone else.")]
340 [WebDisplayName("Waiting on someone else")]
341 [System.ComponentModel.Category("Task Status")]
342 public bool WaitingOnSomeoneElse
343 {
344 get
345 {
346 return bStatusWaitingOnSomeoneElse;
347 }
348 set
349 {
350 bStatusWaitingOnSomeoneElse = value;
351 }
352 }
353 }
354
355 public class CustomDocument
356 {
357 public string Body;
358 public string DocumentID;
359 public string CheckedOutTo;
360 public string site;
361 public string list;
362 }
363 }
Thursday, November 23, 2006
A Fairly Painless Way To Combine Dataset Data
{
object[] vals = dr.ItemArray;
ds.Tables[1].Rows.Add(vals);
}
ItemArray is key.
Thursday, November 02, 2006
Using Resource Files
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<VariablefileName>../Projects/RealEstatePostcard/PostCard.xvp</VariablefileName>
<ProjectFileForVariableEvaluation>../Projects/RealEstatePostcard/PostCard.pf</ProjectFileForVariableEvaluation>
<JobForVariableEvaluation>PDF_Job</JobForVariableEvaluation>
<ShowScrollBars>Yes</ShowScrollBars>
<BevelThickness>1</BevelThickness>
<BevelThicknessInset>3</BevelThicknessInset>
<BevelColorInset>lightGray</BevelColorInset>
<BevelColorTopLeft>lightGray</BevelColorTopLeft>
<BevelColorBottomRight>darkGray</BevelColorBottomRight>
<uiConfiguration> PanelPostCardConfig.xml</uiConfiguration>
<EditImage>Edit Image: Crop and Scale Your Image</EditImage>
<bitmapUpdateMethod>xor</bitmapUpdateMethod>
</Config>
I grabbed a hold of it and set its contents against relevant public property names within my class. Like so:
private void LoadConfigValues()
{
// Create a new XmlDocument object and select the appropriate values.
// Reference the running assembly.
Assembly thisAssembly = Assembly.GetExecutingAssembly();
Stream oStrRead = thisAssembly.GetManifestResourceStream("Burrows.PageFlex.WYSIWYG.Config.Configuration.xml");
XmlDocument xDoc = new XmlDocument();
try
{
xDoc.Load(oStrRead);
}
catch (IOException ioEx)
{
throw ioEx;
}
finally
{
oStrRead.Close();
oStrRead.Dispose();
}
// Loop through doc nodes and assign values to public properties.
XmlNodeList oNodeList = xDoc.SelectNodes("//Config/*");
foreach (XmlNode xN in oNodeList)
{
switch (xN.Name)
{
case "VariablefileName":
this.strVariableFileName = xN.InnerText;
break;
case "ProjectFileForVariableEvaluation":
this.strProjectFileForVariableEvaluation = xN.InnerText;
break;
case "JobForVariableEvaluation":
this.strJobForVariableEvaluation = xN.InnerText;
break;
case "ShowScrollBars":
this.strShowScrollBars = xN.InnerText;
break;
case "BevelThickness":
this.strBevelThickness = xN.InnerText;
break;
case "BevelThicknessInset":
this.strBevelThicknessInset = xN.InnerText;
break;
case "BevelColorInset":
this.strBevelColorInset = xN.InnerText;
break;
case "BevelColorTopLeft":
this.strBevelColorTopLeft = xN.InnerText;
break;
case "BevelColorBottomRight":
this.strBevelColorBottomRight = xN.InnerText;
break;
case "uiConfiguration":
this.strUiConfiguration = xN.InnerText;
break;
case "EditImage":
this.strEditImage = xN.InnerText;
break;
case "bitmapUpdateMethod":
this.strBitmapUpdateMethod = xN.InnerText ;
break;
default:
break;
};
}
}
Fixes to common .NET problems, as well as information on .NET features and solutions to common problems that are not language-specific.
Fixes to common .NET problems, as well as information on .NET features and solutions to common problems that are not language-specific.