Progmatically creating documents Kentico 9 - c#

I've to create a new document in the back end but can not find any useful information on how to do this in Kentico 9.
So far I've got
UserInfo user = UserInfoProvider.GetUserInfo("administrator");
// Creates a tree provider instance using administrator context
TreeProvider tree = new TreeProvider(user);
// Prepare parameters
string siteName = CMS.SiteProvider.SiteContext.CurrentSiteName;
string aliasPath = "/News";
string culture = "en-GB";
bool combineWithDefaultCulture = false;
string classNames = TreeProvider.ALL_CLASSNAMES;
string where = null;
string orderBy = null;
int maxRelativeLevel = -1;
bool selectOnlyPublished = false;
string columns = null;
// Get the example folder
TreeNode parentNode = DocumentHelper.GetDocument(siteName, aliasPath, culture, combineWithDefaultCulture, classNames, where, orderBy, maxRelativeLevel, selectOnlyPublished, columns, tree);
if (parentNode != null)
{
// Create a new node
TreeNode node = TreeNode.New("CMS.News", tree);
// Set the required document properties
node.DocumentName = "Test";
node.DocumentCulture = "en-GB";
// Insert the document
try
{
DocumentHelper.InsertDocument(node, parentNode, tree);
}
catch (Exception ex)
{
EventLogProvider.LogException("Create New News", "EXCEPTION", ex);
}
}
This however throws an error:
Message: [WebFarmTaskManager.CanCreateTask]: Task type 'DICTIONARYCOMMAND' is not supported. The task needs to be registered with WebFarmHelper.RegisterTask method.
Has anyone had experience with doing this in Kentico 9?

Sorry, may be my two cents comes too late but I solved the same issue invoking the following initialization method not mentioned on Kentico docs:
CMS.DataEngine.CMSApplication.Init();

You can create page in content tree like:
// Creates a new instance of the Tree provider
TreeProvider tree = new TreeProvider(MembershipContext.AuthenticatedUser);
// Gets the current site's root "/" page, which will serve as the parent page
TreeNode parentPage = tree.SelectSingleNode(SiteContext.CurrentSiteName, "/", "en-us");
if (parentPage != null)
{
// Creates a new page of the "CMS.MenuItem" page type
TreeNode newPage = TreeNode.New(SystemDocumentTypes.MenuItem, tree);
// Sets the properties of the new page
newPage.DocumentName = "Articles";
newPage.DocumentCulture = "en-us";
// Inserts the new page as a child of the parent page
newPage.Insert(parentPage);
You can find more examples in API Examples documentation for version 9.

Related

c# NavisWorks ModelItem isReadOnly() always true

I try to add some new property in existing category for selected NavisWorks ModelItem`s
There is not so many example over network, and it base on same COM approach.
However there special method to add property available in API.
Only issue that objects is locked.
Is there any way to unlock it?
using ANA = Autodesk.Navisworks.Api;
...
private void addProperty(string category, string prop, string value)
{
var oDoc = Autodesk.Navisworks.Api.Application.ActiveDocument;
ModelItemCollection selectionModelItems = new ModelItemCollection();
ANA.Application.ActiveDocument.CurrentSelection.SelectedItems.CopyTo(selectionModelItems);
//Clear the current selection
ANA.Application.ActiveDocument.CurrentSelection.Clear();
try
{
foreach (ModelItem m in selectionModelItems)
{
foreach (PropertyCategory p in m.PropertyCategories)
{
if (p.DisplayName != category) continue;
var property = new DataProperty(prop, prop, new VariantData(value));
p.Properties.Add(property);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
result of execution:
Properties and categories which are created by Navisworks are read-only.
You can not add or modify properties or categories which are created by Navisworks.
You can only create or add user-defined properties - using COM.
See:
https://adndevblog.typepad.com/aec/2012/05/create-attributes-and-properties-for-model-objects-using-net-api.html
https://adndevblog.typepad.com/aec/2012/08/addmodifyremove-custom-attribute-using-com-api.html
https://forums.autodesk.com/t5/navisworks-api/navisworks-api-add-user-data-tab/td-p/2916866
Here is a code snippet (copied from xiaodong.liang forum post mentioned above) which shows how to add a user-defined property using COM:
private void addProperty() {
ComApi.InwOpState10 state;
state = ComApiBridge.ComApiBridge.State;
ModelItemCollection modelItemCollectionIn = new ModelItemCollection(Autodesk.Navisworks.Api.Application.ActiveDocument.CurrentSelection.SelectedItems);
ComApi.InwOpSelection comSelectionOut =
ComApiBridge.ComApiBridge.ToInwOpSelection(modelItemCollectionIn);
ComApi.InwSelectionPathsColl oPaths = comSelectionOut.Paths();
ComApi.InwOaPath3 oPath = (ComApi.InwOaPath3) oPaths.Last();
ComApi.InwGUIPropertyNode2 propn = (ComApi.InwGUIPropertyNode2) state.GetGUIPropertyNode(oPath, true);
ComApi.InwOaPropertyVec newPvec = (ComApi.InwOaPropertyVec) state.ObjectFactory(Autodesk.Navisworks.Api.Interop.ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, null, null);
ComApi.InwOaProperty newP = (ComApi.InwOaProperty) state.ObjectFactory(Autodesk.Navisworks.Api.Interop.ComApi.nwEObjectType.eObjectType_nwOaProperty, null, null);
newP.name = "LXD_Property_Name";
newP.UserName = "LXD_Property_UserName";
newP.value = "LXD_Property_Value";
newPvec.Properties().Add(newP);
propn.SetUserDefined(0, "LXD_PropertyTab_Name", "LXD_PropertyTab_InteralName", newPvec);
}

Write on other sharepoint site using webserivces

I have 2 Sharepoint 2013 sites.
When user adding new item in SPList at first SPSite -> starting workflow, what must added copy of item in SPList at second SPSite. This is my code:
public void UpdateSPList(string Title)
{
using (AuthenticationSvc.Authentication authSvc = new AuthenticationSvc.Authentication())
{
try
{
using (ListsSvc.Lists list = new ListsSvc.Lists())
{
list.Url = #"http://second-srharepoint-site.com/_vti_bin/Lists.asmx";
list.CookieContainer = new System.Net.CookieContainer();
list.AllowAutoRedirect = true;
list.PreAuthenticate = true;
list.Credentials = new System.Net.NetworkCredential("domain\\username", "password");
string strBatch = "<Method Cmd='New'><Field Name='Title'>" + Title + "</Field> ";
XmlDocument xmlDoc = new XmlDocument();
XmlElement elBatch = xmlDoc.CreateElement("Batch");
elBatch.SetAttribute("OnError", "Continue");
elBatch.InnerXml = strBatch;
XmlNode ndReturn = list.UpdateListItems("SPListName", elBatch);
}
}
finally
{
}
}
}
But on line elBatch.InnerXml = strBatch; I get exception:
$exception {"Unexpected end of file has occurred. The following elements are not closed: Method. Line 1, position 60."}
System.Exception {System.Xml.XmlException}
I don't know how fix this problem. Help me, please.
First, the string isn't valid XML because the closing Method element is missing. It should be
"<Method Cmd='New'><Field Name='Title'>" + Title + "</Field></Method>"
Second, the ASMX services were deprecated back in 2010. You shouldn't use them for any king of development, especially against SP 2013. The client-side object model (CSOM) is a lot simpler and easier to use. There are a lot of examples in the documentation. The snippet that creates a new item is :
// Starting with ClientContext, the constructor requires a URL to the
// server running SharePoint.
ClientContext context = new ClientContext("http://SiteUrl");
// Assume that the web has a list named "Announcements".
List announcementsList = context.Web.Lists.GetByTitle("Announcements");
// We are just creating a regular list item, so we don't need to
// set any properties. If we wanted to create a new folder, for
// example, we would have to set properties such as
// UnderlyingObjectType to FileSystemObjectType.Folder.
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem newItem = announcementsList.AddItem(itemCreateInfo);
newItem["Title"] = "My New Item!";
newItem["Body"] = "Hello World!";
newItem.Update();
context.ExecuteQuery();
No XML fiddling, you simply create a new item, set its properties and call Update

Product_Order verifyOrder API fails when adding guest_disks

I have a C# application in which I imported API methods using wsdl, as described in the Softlayer guidelines.
I'm editing virtual guests by passing a Container_Product_Order_Virtual_Guest_Upgrade structure to the Product_Order service.
Everything works great except for when adding item price IDs for guest_disks, scenario in which after about 6-7 seconds the following exception is thrown:
"The request was aborted: The connection was closed unexpectedly."
This happens with both verifyOrder and placeOrder methods.
I checked Virtual_Guest::getUpgradeItemPrices in order to make sure that the guest disk values are valid(even though passing invalid itempriceIds for the VM results in an specific error response, not in a generic exception such as the one described above).
I can't find any details in the documentation that could give me hints as why I can upgrade anything except guest_disks.
EDIT:
Stripped code as requested:
SoftLayer_Virtual_Guest[] _VMtoEditList = new SoftLayer_Virtual_Guest[1] { -- Vm instance details are retrieved from SL according to the passed VM ID; };
List<SoftLayer_Product_Item_Price> _itemPriceList = new List<SoftLayer_Product_Item_Price>();
foreach (-- collection of properties to be upgraded )
{
SoftLayer_Product_Item_Category _category = new SoftLayer_Product_Item_Category();
_category.categoryCode = -- retrieved from the collection on which I iterate (eg "guest_disk0", "ram", etc.);
SoftLayer_Product_Item_Price _itemPrice = new SoftLayer_Product_Item_Price();
_itemPrice.id = -- the item priceID for the current item;
_itemPrice.idSpecified = true;
_itemPrice.categories = new SoftLayer_Product_Item_Category[1] { _category };
_itemPriceList.Add(_itemPrice);
}
SoftLayer_Product_Item_Price[] _itemPricesArray = _itemPriceList.ToArray();
SoftLayer_Container_Product_Order_Property _property1 = new SoftLayer_Container_Product_Order_Property();
_property1.name = "NOTE_GENERAL";
_property1.value = -- order's description;
SoftLayer_Container_Product_Order_Property _property2 = new SoftLayer_Container_Product_Order_Property();
_property2.name = "MAINTENANCE_WINDOW";
_property2.value = "now";
// Build SoftLayer_Container_Product_Order_Property
SoftLayer_Container_Product_Order_Property[] properties = new SoftLayer_Container_Product_Order_Property[2] { _property1, _property2 };
-- create container
SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade _upgradeContainer = new SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade();
_upgradeContainer.virtualGuests = _VMtoEditList;
_upgradeContainer.prices = _itemPricesArray;
_upgradeContainer.properties = properties;
_upgradeContainer.packageId = 46;
_upgradeContainer.packageIdSpecified = true;
SoftLayer_Product_OrderService service = new SoftLayer_Product_OrderService();
-- authentication structure is created here
SoftLayer_Container_Product_Order _verifiedOrder = service.verifyOrder(_upgradeContainer);
service.placeOrder(_verifiedOrder, false);
Here a have an example to upgrade which works see below. I see that in your code you are adding the packageId which is not required, removed and try again.
Also when you are creating the web references try using the last version of the api in the WSDL url (v3.1)
e.g. https://api.softlayer.com/soap/v3.1/SoftLayer_Hardware_Server?wsdl
//-----------------------------------------------------------------------
// <copyright file="PlaceOrderUpgrade.cs" company="Softlayer">
// SoftLayer Technologies, Inc.
// </copyright>
// <license>
// http://sldn.softlayer.com/article/License
// </license>
//-----------------------------------------------------------------------
namespace VirtualGuests
{
using System;
using System.Collections.Generic;
class PlaceOrderUpgrade
{
/// <summary>
/// Order an upgrade for Virtual Guest
/// This script orders an upgrade for Virtual Guest, in this case we will upgrade the ram for a Virtual Guest,
/// It uses SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade container and SoftLayer_Product_Order::placeOrder
/// method for it.
/// For more information, review the following links:
/// </summary>
/// <manualPages>
/// http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/placeOrder
/// http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade/
/// http://sldn.softlayer.com/reference/services/SoftLayer_Product_Item_Price/
/// </manualPages>
static void Main(String [] args)
{
// You SoftLayer username
string username = "set me";
// Your SoftLayer API key.
string apiKey = "set me";
// Define the virtual guest id to place an upgrade
int virtualId = 13115425;
// Creating a connection to the SoftLayer_Product_Order API service and
// bind our API username and key to it.
authenticate authenticate = new authenticate();
authenticate.username = username;
authenticate.apiKey = apiKey;
SoftLayer_Product_OrderService orderService = new SoftLayer_Product_OrderService();
orderService.authenticateValue = authenticate;
// Build a SoftLayer_Product_Item_Price objects with the ids from prices that you want to order.
// You can retrieve them with SoftLayer_Product_Package::getItemPrices method
int[] prices = {
1645
};
List<SoftLayer_Product_Item_Price> pricesList = new List<SoftLayer_Product_Item_Price>();
foreach (var price in prices)
{
SoftLayer_Product_Item_Price newPrice = new SoftLayer_Product_Item_Price();
newPrice.id = price;
newPrice.idSpecified = true;
pricesList.Add(newPrice);
}
// Build SoftLayer_Container_Product_Order_Property object for the upgrade
SoftLayer_Container_Product_Order_Property property = new SoftLayer_Container_Product_Order_Property();
property.name = "MAINTENANCE_WINDOW";
property.value = "NOW";
List<SoftLayer_Container_Product_Order_Property> propertyList = new List<SoftLayer_Container_Product_Order_Property>();
propertyList.Add(property);
// Build SoftLayer_Virtual_Guest object with the id from vsi that you wish to place an upgrade
SoftLayer_Virtual_Guest virtualGuest = new SoftLayer_Virtual_Guest();
virtualGuest.id = virtualId;
virtualGuest.idSpecified = true;
List<SoftLayer_Virtual_Guest> virtualGuests = new List<SoftLayer_Virtual_Guest>();
virtualGuests.Add(virtualGuest);
// Build SoftLayer_Container_Product_Order object containing the information for the upgrade
//SoftLayer_Container_Product_Order orderTemplate = new SoftLayer_Container_Product_Order();
SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade orderTemplate = new SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade();
orderTemplate.containerIdentifier = "SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade";
orderTemplate.prices = pricesList.ToArray();
orderTemplate.properties = propertyList.ToArray();
orderTemplate.virtualGuests = virtualGuests.ToArray();
try
{
// We will check the template for errors, we will use the verifyOrder() method for this.
// Replace it with placeOrder() method when you are ready to order.
SoftLayer_Container_Product_Order verifiedOrder = orderService.verifyOrder(orderTemplate);
Console.WriteLine("Order Verified!");
}
catch (Exception e)
{
Console.WriteLine("Unable to place an upgrade for Virtual Guest: " + e.Message);
}
}
}
}
Let me know if this helps
Regards

How to add two actions depending on 'type' attribute of element in XML using webdriver in c#

I have elements stored in a config.xml file as part of my project, currently I have a method to 'setData' which will find the element by the id and then set its value to the user input (using a webdriver instance called FireFoxBrowser)
I want to add a type attribute to the xml to differentiate between 'inputs' which will use the current code and 'button' to add code that will click anything with this type. How can I use webdriver to write this code?
public void setData(string elementName, string elementValue)
{
XmlDocument docXml = null;
try
{
docXml = new XmlDocument();
string xmlPath = new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName + #"\config.xml";
docXml.Load(xmlPath);
XmlNode nd = docXml.SelectSingleNode(string.Format(#"//page[#url='{0}']", FireFoxBrowser.Url.ToString()));
if (nd != null)
{
var id = nd.SelectSingleNode(string.Format(#"element[#name='{0}']", elementName)).Attributes["id"].Value;
FireFoxBrowser.FindElement(By.Id(id)).Clear();
FireFoxBrowser.FindElement(By.Id(id)).SendKeys(elementValue);
}
}
finally
{
if (docXml != null)
docXml = null;
}
I was able to achieve this using the following line of code which differentiates between type attribute set:
var id = nd.SelectSingleNode(string.Format(#"element[#name='{0}']", elementName)).Attributes["id"].Value;

VS Extension - disabling errors from embedded code editor

I want to show c# source code with syntax highlighting and theme coloring inside a wpf control. This is for preview only and I don't need any editing capabilities.
I found some code samples on how to embed a code editor which receives a file path to load.
I loaded it with a temp file I created - and it works, well almost...
The problem is that the loaded code have parsing errors which shows up in the error list.
Is there a way to set those errors to not appear in the error list?
Here is the code:
IVsInvisibleEditorManager invisibleEditorManager = (IVsInvisibleEditorManager)ServiceProvider.GlobalProvider.GetService(typeof(SVsInvisibleEditorManager));
ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(csTempFilePath, pProject: null,dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING,
pFactory: null, ppEditor: out this.invisibleEditor));
//The doc data is the IVsTextLines that represents the in-memory version of the file we opened in our invisibe editor, we need
//to extract that so that we can create our real (visible) editor.
IntPtr docDataPointer = IntPtr.Zero;
Guid guidIVSTextLines = typeof(IVsTextLines).GUID;
ErrorHandler.ThrowOnFailure(this.invisibleEditor.GetDocData(fEnsureWritable: 1, riid: ref guidIVSTextLines, ppDocData: out docDataPointer));
try
{
IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer);
//Get the component model so we can request the editor adapter factory which we can use to spin up an editor instance.
IComponentModel componentModel = (IComponentModel)ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel));
IVsEditorAdaptersFactoryService editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
//Create a code window adapter.
this.codeWindow = editorAdapterFactoryService.CreateVsCodeWindowAdapter(OleServiceProvider);
IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)this.codeWindow;
INITVIEW[] initView = new INITVIEW[1];
codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER,
VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter,
szNameAuxUserContext: "",
szValueAuxUserContext: "",
InitViewFlags: 0,
pInitView: initView);
ErrorHandler.ThrowOnFailure(this.codeWindow.SetBuffer((IVsTextLines)docData));
//Get our text view for our editor which we will use to get the WPF control that hosts said editor.
ErrorHandler.ThrowOnFailure(this.codeWindow.GetPrimaryView(out this.textView));
//Get our WPF host from our text view (from our code window).
IWpfTextViewHost textViewHost = editorAdapterFactoryService.GetWpfTextViewHost(this.textView);
textViewHost.TextView.Options.SetOptionValue(DefaultTextViewHostOptions.ChangeTrackingId, false);
textViewHost.TextView.Options.SetOptionValue(DefaultTextViewOptions.ViewProhibitUserInputId, true);
var dte = ContainerFactory.GetContainer().Resolve<DTE2>();
var projectItem = dte.Solution.FindProjectItem(csTempFilePath);
projectItem.Properties.Item("BuildAction").Value = prjBuildAction.prjBuildActionNone;
return textViewHost.HostControl;
}
finally
{
if (docDataPointer != IntPtr.Zero)
{
//Release the doc data from the invisible editor since it gave us a ref-counted copy.
Marshal.Release(docDataPointer);
}
}
I've tried to remove the errors from the error list manually. But it didn't work - I think it's because i can only remove errors that I added previously. Here is the code I tried using to remove the errors:
public void RemoveTempFileErrors()
{
var provider = new ErrorListProvider(ServiceProvider.GlobalProvider)
{
ProviderName = "MyProvider",
ProviderGuid = new Guid("41C0915D-A0F4-42B2-985F-D1CC5F65BFFC") // my provider guid
};
var vsTaskList1 = (IVsTaskList) Package.GetGlobalService(typeof (IVsTaskList));
uint providerCookie;
vsTaskList1.RegisterTaskProvider(provider, out providerCookie);
vsTaskList1.RefreshTasks(providerCookie);
var vsTaskList2 = (IVsTaskList2)Package.GetGlobalService(typeof(IVsTaskList));
provider.SuspendRefresh();
IVsEnumTaskItems enumerator;
vsTaskList1.EnumTaskItems(out enumerator);
IVsTaskItem[] arr = new IVsTaskItem[1];
while (enumerator.Next(1, arr, null) == 0)
{
string doc;
arr[0].Document(out doc);
if (doc == csTempFilePath)
{
vsTaskList2.RemoveTasks(providerCookie, 1, arr);
}
}
provider.ResumeRefresh();
provider.Refresh();
vsTaskList1.UnregisterTaskProvider(providerCookie);
}
I solved it partially -
The parsing errors were caused because the code was a method without a class. So i wrapped the method in a class and used an elision buffer to show only the method without the wrapper class
The elision buffer code goes like this:
var subsetSnapshot = new SnapshotSpan(textSnapshot.Lines.First().EndIncludingLineBreak, textSnapshot.Lines.Last().Start);
var projectionBufferFactory = componentModel.GetService<IProjectionBufferFactoryService>();
var projBuffer = projectionBufferFactory.CreateElisionBuffer(null,
new NormalizedSnapshotSpanCollection(subsetSnapshot), ElisionBufferOptions.None);
IVsTextBuffer bufferAdapter = editorAdapterFactoryService.CreateVsTextBufferAdapterForSecondaryBuffer(OleServiceProvider, projBuffer);
projTextView = editorAdapterFactoryService.CreateVsTextViewAdapter(OleServiceProvider);
projTextView.Initialize((IVsTextLines)bufferAdapter, IntPtr.Zero,
(uint)TextViewInitFlags.VIF_HSCROLL | (uint)TextViewInitFlags.VIF_VSCROLL | (uint)TextViewInitFlags3.VIF_NO_HWND_SUPPORT,
new[] { new INITVIEW { fSelectionMargin = 0, fWidgetMargin = 0, fVirtualSpace = 0, fDragDropMove = 0 } };
IWpfTextViewHost projTextViewHost = editorAdapterFactoryService.GetWpfTextViewHost(projTextView);

Categories

Resources