Revit API - Wrong full class name - c#

I'm very new to C# and coding. If possible I'm after some assistance figuring out how to fix this piece of code up to work.
They work individually. I can create a new button on the ribbon and execute the standard hello world. i also have a macro which works where I can remove all my sheets and views successfully but trying to combine the two is causing big difficulties! The code builds OK but I'm getting this error inside revit:
'Failed to initialize the add-in "Delete Views" because the class
"DeleteViews" cannot be found in the add-in assembly.The FullClassName
provides the enrty point for Revit to call add-in application. For
Revit to run the add-in, you must ensure this class implements the
"Autodesk.Revit.UI.ExternalCommand" interface.'
I'm pretty sure my problem is referencing in this 2nd bit of code. i know I'm not calling it up correctly but haven't been able to find any solutions.
Apologies if this is a dumb question but would really appreciate any help to help me learn!
Thanks for any help you can give me
The code:
namespace BGPanel
{
public class CsBGPanel : IExternalApplication
{
public UIDocument ActiveUIDocument { get; private set; }
public Result OnStartup(UIControlledApplication application)
{
RibbonPanel ribbonPanel = application.CreateRibbonPanel("Tools");
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
PushButtonData buttonData = new PushButtonData("cmdDeleteViews",
"Delete Views", thisAssemblyPath, "BGPanel.DeleteViews");
PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
pushButton.ToolTip = "Delete all sheets, schedules & views except structural plans";
Uri uriImage = new Uri(#"C:\Revit_API\Revit_2015\32px-Broom.png");
BitmapImage largeImage = new BitmapImage(uriImage);
pushButton.LargeImage = largeImage;
return Result.Succeeded;
}
public void DeleteViews()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = uidoc.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();
using (Transaction t = new Transaction(doc, "Delete Views"))
{
t.Start();
int x = 0;
foreach (Element e in collection)
{
try
{
View view = e as View;
switch (view.ViewType)
{
case ViewType.FloorPlan:
break;
case ViewType.EngineeringPlan:
break;
case ViewType.ThreeD:
break;
default:
doc.Delete(e.Id);
x += 1;
break;
}
}
catch (Exception ex)
{
View view = e as View;
TaskDialog.Show("Error", e.Name + "\n" + "\n" + ex.Message);
TaskDialog.Show("Error", ex.Message);
}
}
t.Commit();
TaskDialog.Show("BG_API DeleteViews", "Views Deleted: " + x.ToString());
}
}
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
}
}

First, instead typing the class name yourself, consider using Reflection like:
typeof(YourClassName).FullName
Second, every command in Revit requires its own class that implements IExternalCommand. I haven't tested, but your code should be something like the following:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Media.Imaging;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace BGPanel
{
public class CsBGPanel : IExternalApplication
{
public Result OnStartup(UIControlledApplication application)
{
RibbonPanel ribbonPanel = application.CreateRibbonPanel("Tools");
string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
PushButtonData buttonData = new PushButtonData("cmdDeleteViews",
"Delete Views", thisAssemblyPath, typeof(DeleteViews).FullName);
PushButton pushButton = ribbonPanel.AddItem(buttonData) as PushButton;
pushButton.ToolTip = "Delete all sheets, schedules & views except structural plans";
Uri uriImage = new Uri(#"C:\Revit_API\Revit_2015\32px-Broom.png");
BitmapImage largeImage = new BitmapImage(uriImage);
pushButton.LargeImage = largeImage;
return Result.Succeeded;
}
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
}
public class DeleteViews : IExternalCommand
{
// this will not work...
//public UIDocument ActiveUIDocument { get; private set; }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument; //this.ActiveUIDocument;
Document doc = uidoc.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> collection = collector.OfClass(typeof(View)).ToElements();
using (Transaction t = new Transaction(doc, "Delete Views"))
{
t.Start();
int x = 0;
foreach (Element e in collection)
{
try
{
View view = e as View;
switch (view.ViewType)
{
case ViewType.FloorPlan:
break;
case ViewType.EngineeringPlan:
break;
case ViewType.ThreeD:
break;
default:
doc.Delete(e.Id);
x += 1;
break;
}
}
catch (Exception ex)
{
View view = e as View;
TaskDialog.Show("Error", e.Name + "\n" + "\n" + ex.Message);
TaskDialog.Show("Error", ex.Message);
}
}
t.Commit();
TaskDialog.Show("BG_API DeleteViews", "Views Deleted: " + x.ToString());
}
return Result.Succeeded; // must return here
}
}
}

You should work through the Revit API getting started material before doing anything else at all, especially the DevTV and My First Revit Plugin video tutorials:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#2
Then this question and many other fundamental issues will be answered up front, and you will save yourself and others some effort and head-scratching.

I needed to add a line before the IExternalCommand because of transaction errors when I clicked my button.
[Transaction(TransactionMode.Manual)]

The first answer to this question suggests using the reflection "typeof(YourClassName).FullName" When the sample code is tried it returns a error, understandably as Augusto says he did not test his example. Just adding for anyone down the road... If you use "typeof(DeleteViews).FullName" you would need to cast it into a string variable before the code in his example would work.

Related

Revit API SizeTableManager.RemoveSizeTable() not working?

I'm trying to remove all Lookup Tables that start with a specific prefix inside all families.
The method "sizeTableManager.RemoveSizeTable(tableToRemove)" returns true as if it succeeded but when I go edit the families in the project and bring up the Lookup Tables list they are still there.
The transaction seems to be committing with no errors too, which is even more puzzling...
Any ideas as to what I'm doing wrong?
This is my code so far:
string existingPrefix = "ExistingPrefix_";
Document doc = this.ActiveUIDocument.Document;
FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> elements = collector.OfClass(typeof(Family)).ToElements();
foreach (var element in elements)
{
using (Transaction t = new Transaction(doc, "flush old lookup tables"))
{
t.Start();
FamilySizeTableManager sizeTableManager = FamilySizeTableManager.GetFamilySizeTableManager(doc, element.Id);
if(sizeTableManager != null)
{
foreach (var tableToRemove in sizeTableManager.GetAllSizeTableNames())
{
if(tableToRemove.StartsWith(existingPrefix))
{
bool result = sizeTableManager.RemoveSizeTable(tableToRemove);
if(result)
{
// TaskDialog.Show("Success", "Removed " + tableToRemove + " from " + element.Name);
var test = "test";
}
else
{
TaskDialog.Show("Warning", "Unable to remove " + tableToRemove + " from " + element.Name);
}
}
}
}
var commitResult = t.Commit();
}
}
Thanks in advance!
Well, turns out that the RemoveSizeTable() method was indeed working, but that I had to regenerate the document for the changes to take effect:
using (Transaction t = new Transaction(doc, "regenerate document"))
{
t.Start();
doc.Regenerate();
t.Commit();
}
Discovered this after noticing that saving the document caused the changes to take effect.

C# - Visual Studio - 'object' does not contain a definition for 'ExecuteQuery'

I am trying to add code to an existing project that will check for existence of a device in SCCM and delete it if it does exist. I seem to be missing something, in that particular block of code. I get an error - 'object' does not contain a definition for 'ExecuteQuery' and no extension method 'ExecuteQuery' accepting a first argument of type 'object' could be found.
Here is the C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net.NetworkInformation;
using SupportToolkit.Models;
using SupportToolkit.WindowsAutomationServices;
using NLog;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Management;
namespace SupportToolkit.Controllers
{
public class TPOSRecordDeletionController : Controller
{
private static Logger recordDeletionLogger = LogManager.GetCurrentClassLogger();
[Authorize(Roles = #"nor\NST_RIT_Users,nor\NST_STM_Users,nor\NST_Admin_Users,nor\NST_CORP_Users")]
// GET: TPOSRecordDeletion
public ActionResult Index(TPOSRecordDeletionModel model)
{
if (model.ComputerName != null)
{
}
if (ModelState.IsValid)
{
if (!(string.IsNullOrEmpty(model.btnDeleteRecord)))
{
InvokeRecordDeletion(model);
}
}
return View(model);
}
[Authorize(Roles = #"nor\NST_RIT_Users,nor\NST_STM_Users,nor\NST_Admin_Users,nor\NST_CORP_Users")]
public string InvokeRecordDeletion(TPOSRecordDeletionModel model)
{
model.Status = "Running Service";
var windowsAutomationService = new WindowsAutomationServicesClient();
string shortServiceOutput;
var serviceAction = "Remove-TPOSRecords";
var SCCMServer = "server.nor.net";
var siteCode = "PO60";
string[] recordDeletionArguments = new string[1];
recordDeletionArguments[0] = model.ComputerName;
model.Status = "Processing" + model.ComputerName;
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
// Use the default Ttl value which is 128,
// but change the fragmentation behavior.
options.DontFragment = true;
// Create a buffer of 32 bytes of data to be transmitted.
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
PingReply reply = pingSender.Send(model.ComputerName, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
model.Status = model.ComputerName + "is currently online and will not be removed!";
}
else
{
// set up domain context
using (var ctx = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain))
{
// find a computer
ComputerPrincipal computer = ComputerPrincipal.FindByIdentity(ctx, model.ComputerName);
if (computer == null)
{
model.Status = model.ComputerName + "does not exist in Active Directory.";
}
else
{
computer.Delete();
model.Status = model.ComputerName + "successfully removed from Active Directory!";
}
//insert code here for checking for existence of computer in SCCM and removing from SCCM if exists
SmsNamedValuesDictionary namedValues = new SmsNamedValuesDictionary();
WqlConnectionManager connection = new WqlConnectionManager(namedValues);
connection.Connect("s0319p60.nordstrom.net");
foreach (IResultObject computerobject in connection.QueryProcessor.ExecuteQuery("Select ResourceID From SMS_R_System Where Name ='" + model.ComputerName + "'"))
{
if (computerobject == null)
{
model.Status = model.ComputerName + "does not exist in SCCM.";
}
else
{
computerobject.Delete();
model.Status = model.ComputerName + "successfully removed from SCCM!";
}
}
}
var userName = User.Identity.Name;
var serviceOutput = windowsAutomationService.RunAutomationService(serviceAction, userName, recordDeletionArguments);
recordDeletionLogger.Info(userName + " is attempting to remove the record " + model.ComputerName);
if (serviceOutput.Length >= 7)
{
shortServiceOutput = serviceOutput.Substring(0, 7);
shortServiceOutput = shortServiceOutput.ToLower();
}
else
{
shortServiceOutput = serviceOutput;
shortServiceOutput = shortServiceOutput.ToLower();
}
if (shortServiceOutput == "success")
{
model.Status = "Successfully removed " + model.ComputerName + " from SCCM and Active Directory";
recordDeletionLogger.Info(userName + " successfully removed " + model.ComputerName + " from SCCM and Active Directory");
return "Success";
}
else
{
model.Status = "Failure removing " + model.ComputerName + " from SCCM and Active Directory. Unknown Error";
recordDeletionLogger.Info(userName + " failed to remove " + model.ComputerName + " from SCCM and Active Directory");
return "Failure";
}
}
}
}
internal interface IResultObject
{
//void Delete();
void Delete();
}
internal class WqlConnectionManager
{
private SmsNamedValuesDictionary namedValues;
public WqlConnectionManager(SmsNamedValuesDictionary namedValues)
{
this.namedValues = namedValues;
}
public object QueryProcessor { get; internal set; }
internal void Connect(string v)
{
throw new NotImplementedException();
}
public object ExecuteQuery { get; internal set; }
}
internal class SmsNamedValuesDictionary
{
public SmsNamedValuesDictionary()
{
}
}
Well - after a few days of searching, I FINALLY figured out the issue.
The entire block of code at the end, was not necessary. The issue was that there were missing assembly references and using statements in the code. Specifically:
using Microsoft.ConfigurationManagement.ManagementProvider;
using Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine;
The corresponding DLLs also needed to be added to the project as references.
I hope this helps someone who runs into similar issues and is not versed in C# coding. I myself am only versed in PowerShell, so figuring this out took a lot of work for me. Thanks.
You create a custom "connection" object:
WqlConnectionManager connection = new WqlConnectionManager(namedValues);
Then call a method on one of its properties:
connection.QueryProcessor.ExecuteQuery("...")
But what is that QueryProcessor property?...
public object QueryProcessor { get; internal set; }
It's an object. As the error states, object doesn't have a method called ExecuteQuery. (It doesn't have very many methods or properties at all, really.)
I can't really tell from this code (maybe I'm missing something?) what specific type you're expecting QueryProcessor to be, but it should definitely be something more specific than object. Something analogous to a SQLCommand object, perhaps? Essentially, whatever type would have that ExecuteQuery method.
If there's a compelling reason in the existing codebase for this to be of type object, you'd need to determine what that reason is. There seems to be a lot of use of object here, which smells of some bad design choices from before you got there.

Switch statement that makes different child classes of one parent class does not work

hopefully this isnt too complicated, I am just wondering why this switch statement isnt working. Band is the parent class and the child classes are different types of bands (RockBand, JazzCombo, SoloAct, default). When I have the switch statement in place it catches and produces the error, only loading 2 bands. Is there anything wrong with the syntax?
class Bands
{
private List<Band> bands = new List<Band>();
private Dictionary<string, Band> bandsByName = new Dictionary<string, Band>();
public Bands()
{
string fileName = #"C:\Users\Lkvideorang\Documents\Visual Studio 2013\Projects\KernRadio\KernRadio\bin\Debug\bands.txt";
try
{
using (StreamReader myRdr = new StreamReader(fileName))
{
string line;
while ((line = myRdr.ReadLine()) != null)
{
string[] lineAra = line.Split('|');
switch (lineAra[1])
{
case "RockBand":
Band newBand = new RockBand(lineAra);
bands.Add(newBand);
bandsByName.Add(newBand.Name, newBand);
break;
case "JazzCombo":
Band newt = new JazzCombo(lineAra);
bands.Add(newt);
bandsByName.Add(newt.Name, newt);
break;
case "SoloAct":
Band newB = new SoloAct(lineAra);
bands.Add(newB);
bandsByName.Add(newB.Name, newB);
break;
default:
Band ddd = new Band(lineAra);
bands.Add(ddd);
bandsByName.Add(ddd.Name, ddd);
break;
}
}
}
Console.WriteLine("loaded " + bands.Count + " bands");
}
catch
{
Console.WriteLine("Error reading file! Read " + bands.Count + " tunes.");
}
}
rockband class. This is where my main trouble is, my professor wants us to make the members of the band class Musician but I dont really understand how to utilize it and assign with that class. Ill post that class too.
class RockBand : Band
{
private Musician vocalist;
private Musician bass;
private Musician drums;
private Musician guitar;
public RockBand (string[] lineAra) : base (lineAra,)
{
vocalist.Name = lineAra[2];
}
}
Class Musician
class Musician
{
string name;
string instrument;
public string Name
{
get { return name; }
set { name = value; }
}
public string Instrument
{
get { return instrument; }
set { instrument = value; }
}
public Musician(string [] lineAra)
{
name = lineAra[0];
instrument = lineAra[1];
}
}
The txt file looks like this
Al & GenJam|JazzCombo|GenJam|GenJam|GenJam|GenJam|Al Biles
John Coltrane Quartet|JazzCombo|McCoy Tyner|Jimmy Garrison|Elvin Jones|John Coltrane
Beatles|RockBand|John Lennon|Paul McCartney|Ringo Starr|George Harrison
Miles Davis Quintet|JazzCombo|Herbie Hancock|Ron Carter|Tony Williams|Miles Davis|Wayne Shorter
Michael Jackson|SoloAct
Weird Al|SoloAct
Polka Punks|PolkaBand
Herbie Hancock Trio|JazzCombo|Herbie Hancock|Ron Carter|Tony Williams
the dudes.txt
John Lennon|guitar
Paul McCartney|bass
Ringo Starr|drums
George Harrison|guitar
Al Biles|trumpet
GenJam|code
Michael Jackson|vocals
Weird Al|accordian
John Coltrane|sax
Miles Davis|trumpet
Wayne Shorter|sax
McCoy Tyner|piano
Jimmy Garrison|bass
Elvin Jones|drums
Tony Williams|drums
Herbie Hancock|piano
Ron Carter|bass
Also if there is a way to have newBand repeated in each case instead of me different variables for each that would be amazing. Thanks in advance!!
The reason you were getting the NullReferenceException is because you are trying to set the names of musicians before you have initialised the musician objects. What you want to do is this:
public class RockBand : Band
{
private Musician vocalist;
private Musician bass;
private Musician drums;
private Musician guitar;
public RockBand (string[] lineAra)
: base(lineAra)
{
if (lineAra.Length >= 3)
vocalist = new Musician(lineAra[2], "Vocals");
if (lineAra.Length >= 4)
bass = new Musician(lineAra[3], "bass");
if (lineAra.Length >= 5)
drums = new Musician(lineAra[4], "Drums");
if (lineAra.Length >= 6)
guitar = new Musician(lineAra[5], "Guitar");
}
}
You will have to add another constructor to Musician for this:
public Musician(string name, string instrument)
{
this.Name = name;
this.Instrument = instrument;
}
Notice I've also added a check to see if the element exists in the array before trying to access it. This is to avoid an IndexOutOfRangeException.
You can also simplify the code for loading the file:
public Bands()
{
string fileName = #"C:\Users\Lkvideorang\Documents\Visual Studio 2013\Projects\KernRadio\KernRadio\bin\Debug\bands.txt";
string[] allLines;
try
{
allLines = File.ReadAllLines(fileName);
}
catch (Exception ex)
{
Console.WriteLine("Error reading file! Exception: " + ex.Message);
return;
}
bands = new List<Band>();
foreach (var line in allLines)
{
try
{
string[] lineAra = line.Split('|');
if (lineAra.Length < 2) continue;
switch (lineAra[1])
{
case "RockBand":
bands.Add(new RockBand(lineAra));
break;
case "JazzCombo":
bands.Add(new JazzCombo(lineAra));
break;
case "SoloAct":
bands.Add(new SoloAct(lineAra));
break;
default:
bands.Add(new Band(lineAra));
break;
}
}
catch (Exception ex)
{
Console.WriteLine("Error parsing line {0}. Exception: {1}", line, ex.Message);
}
}
bandsByName = bands.ToList().ToDictionary(x => x.Name, x => x);
Console.WriteLine("loaded " + bands.Count + " bands");
}
Here I've changed the stream reader to just File.ReadAllLines and used .ToDictionary() to create the lookup after all the bands have been loaded.
I also added error handling for each line so that you will be able to see which line is causing the error if you have problems in future.
If you have any problems understanding changes let me know.
You are using string.Split('|') incorrectly.
You first need to get the entire string, and then call split just once.
using (StreamReader myRdr = new StreamReader(fileName))
{
string entireText;
if((entireText= myRdr.ReadToEnd()) != null)
{
string[] entireTextArray = entireText.Split('|');
foreach(string band in entireTextArray )
{
switch (band)
{
case "RockBand":
Band newBand = new RockBand(lineAra);
bands.Add(newBand);
bandsByName.Add(newBand.Name, newBand);
break;
case "JazzCombo":
Band newt = new JazzCombo(lineAra);
bands.Add(newt);
bandsByName.Add(newt.Name, newt);
break;
case "SoloAct":
Band newB = new SoloAct(lineAra);
bands.Add(newB);
bandsByName.Add(newB.Name, newB);
break;
default:
Band ddd = new Band(lineAra);
bands.Add(ddd);
bandsByName.Add(ddd.Name, ddd);
break;
}
}
}
}

Update in couchbase

I need some help in update using couchbase. I have a task in my page. If the user clicks the like then the likes count should be updated in my couchbase bucket. I have tried my own update handler code but that has some time latency. I have included my update code too below.
This is my code for liking a task...
public ResponseVO LikeTask(LikeVO likeVO)
{
ResponseVO response = new ResponseVO();
try
{
if (!isLiked(likeVO.TaskID, likeVO.UserID))
{
UpdateTaskDB likeUpdate = new UpdateTaskDB();
UpdateTaskVO updatetaskvo = new UpdateTaskVO();
updatetaskvo.FieldName = "Likes";
LikeVO tempvo = new LikeVO();
tempvo.LikedOn = DateTime.Now.ToString();
tempvo.UserID = likeVO.UserID;
tempvo.UserName = likeVO.UserName;
tempvo.TaskID = likeVO.TaskID;
updatetaskvo.ObjectValue = tempvo;
updatetaskvo.TaskID = likeVO.TaskID;
likeUpdate.UpdateDocument(updatetaskvo);
}
response.StatusMessage = "Liked Successfully";
}
catch (Exception ex)
{
response.StatusCode = "0";
response.StatusMessage = ex.Message;
}
return response;
}
My own update handler code:
public class UpdateTaskDB
{
CouchbaseClient oCouchbase;
public UpdateTaskDB()
{
oCouchbase = new CouchbaseClient("vwspace", "");
}
public TaskVO GetTaskByID(string task_id)
{
TaskVO results = null;
try
{
String str1;
str1 = (String)oCouchbase.Get(task_id);
results = JsonConvert.DeserializeObject<TaskVO>(str1);
}
catch (Exception ex)
{
}
return results;
}
public void UpdateDocument(UpdateTaskVO inputParams)
{
try
{
var client = new CouchbaseClient("vwspace", "");
TaskVO taskDoc = GetTaskByID(inputParams.TaskID);
switch (inputParams.FieldName)
{
case "Likes":
List<LikeVO> docLikes = taskDoc.likes;
docLikes.Add((LikeVO)inputParams.ObjectValue);
taskDoc.likes = docLikes;
break;
case "UnLike":
LikeVO unlikevo = (LikeVO)inputParams.ObjectValue;
for (int count = 0; count < taskDoc.likes.Count; count++)
{
if (taskDoc.likes[count].UserID.Equals(unlikevo.UserID))
{
unlikevo = taskDoc.likes[count];
break;
}
}
taskDoc.likes.Remove(unlikevo);
break;
default:
break;
}
String json = JsonConvert.SerializeObject(taskDoc);
client.Store(StoreMode.Set, inputParams.TaskID, json);
}
catch (Exception ex)
{
Console.Write("Exception :" + ex.Message);
}
}
}
Is ther any other way to handle this update in couchbase? Kindly help me out..
The latency you're seeing is likely due to the fact that you're creating two instances of the CouchbaseClient for each click. Creating an instance of a CouchbaseClient is an expensive operation, because of the bootstrapping and configuration setup that takes place.
There are a couple of different approaches you can take to minimize how frequently you create CouchbaseClient instances. One would be to create a static client that is reused by your data access classes. Another approach for web apps is to associate instances with HttpApplication instances. For an example of the Web approach, see my (incomplete) sample project on GitHub below.
https://github.com/jzablocki/couchbase-beer.net/blob/master/src/CouchbaseBeersWeb/Models/WebRepositoryBase%271.cs
Also, I would suggest using CAS operations when updating a document's like count. You want to make sure that a "like" vote doesn't cause the entire document to be update from a stale read.
For example:
public TaskVO GetTaskByID(string task_id)
{
var getResult = oCouchbase.ExecuteGet<string>(task_id);
var results = JsonConvert.DeserializeObject<TaskVO>(str1.Value);
results.Cas = getResult.Cas; //Here I'm suggesting adding a Cas property to your TaskVO
return results;
}
Then on your update:
public void UpdateDocument(UpdateTaskVO inputParams)
{
try
{
TaskVO taskDoc = GetTaskByID(inputParams.TaskID);
switch (inputParams.FieldName)
{
...
}
String json = JsonConvert.SerializeObject(taskDoc);
client.ExecuteStore(StoreMode.Set, inputParams.TaskID, json, taskDoc.Cas);
//this will fail if the document has been updated by another user. You could use a retry strategy
}
catch (Exception ex)
{
Console.Write("Exception :" + ex.Message);
}
}

How to optimize this code to create document libraries

This is sharepoint code, but I know c# developers would understand it.
I cant think a way right now to optimize it.
The idea is to create a document library based on the creation of an event, The name of the document library is the startdate in some format + the event title.
The problem is when the user makes many events, the same day, with the same title.
I did it with an IF for only one occurence of the duplication. But there should be another better way to do it.
The idea is to concatenate a number at the end of the doc library /1/2/3 etc.
using (SPSite oSPSite = new SPSite(SiteUrl))
{
using (SPWeb oSPWeb = oSPSite.RootWeb)
{
if (oSPWeb.Lists[DocumentLibraryName] == null)
{
Guid ID = oSPWeb.Lists.Add(DocumentLibraryName, DocumentLibraryName + System.DateTime.Now.ToString(), SPListTemplateType.DocumentLibrary);
SPList oSPList = oSPWeb.Lists[ID];
DocumentLibraryLink = oSPList.DefaultViewUrl;
oSPList.OnQuickLaunch = false;
oSPList.Update();
}
else
{
if (oSPWeb.Lists[DocumentLibraryName + "/1"] == null)
{
Guid ID = oSPWeb.Lists.Add(DocumentLibraryName + "/1", DocumentLibraryName + System.DateTime.Now.ToString(), SPListTemplateType.DocumentLibrary);
SPList oSPList = oSPWeb.Lists[ID];
DocumentLibraryName = DocumentLibraryName + "/1";
DocumentLibraryLink = oSPList.DefaultViewUrl;
oSPList.OnQuickLaunch = false;
oSPList.Update();
}
}
}
}
}
In pseudo-code:
string docLibNameBase ="myLibname";
string docLibNameTemp = docLibNameBase; //we start with the calculated title
int iCounter = 1;
//we check if the currently calculated title is OK
while (listExists(docLibNameTemp, yourWeb)) {
docLibNameTemp = docLibNameBase + "/" + iCounter.toString();
}
//this is where you create the new list using docLibNameTemp as a good title
bool listExists(string docLibName, SPWeb web){
try {
//if there is no list with such name, it will throw an exception
return (web.Lists[docLibname]!=null);
} catch{
return false;
}
}

Categories