How to override VBScript GetObject method in .NET - tridion

I am having below code in VBScript
' Retrieve the keyword category for page section names
Set SectionCat = TDSE.GetObject(WebdavToUri(getPublicationWebDav(WEBDAV_SECTION_CAT)), 1)
' Retrieve the localized section keyword
Set SectionKeyword = SectionCat.GetKeywordByTitle(meta)
' Open the English translated section keyword
Set SectionKeyword = TDSE.GetObject(SectionKeyword.Id, 1, WEBDAV_UKEN_PUB)
SectionName = SectionKeyword.Title
Where WEBDAV_UKEN_PUB is the WebDavPath, now in VBScript GetObject method we have got option to pass three parameters 1) Item.ID, 2) TDSDefines.OpenModeEditWithFallback and 3) WebDavPath from where to make the object.
Now I want to write same logic in 2009 .Net templating, below is the sample code, I am trying to write but not able to get rid of VBScript Object.
Category cat = engine.GetSession().GetObject(WebdavToUri(getPublicationWebDav(Constants.WEBDAV_SECTION_CAT,package,engine), engine)) as Category;
if (cat != null)
{
//_log.Info("Category" + cat.Title);
Keyword keyword = cat.GetKeywordByTitle(meta);
//_log.Info("keyword 1" + keyword.Title);
keyword = engine.GetObject(Constants.WEBDAV_UKEN_PUB) as Keyword;
//_log.Info("keyword 2 " + keyword.Title);
if (keyword != null)
{
sectionName = keyword.Title;
}
keyword = null;
I am able to create Category object, however when I am trying to make Keyword object its getting failed and giving object reference error.
Do we have any class or method which work same like VBScript GetObject which will make the Object from the passed webdavpath or can somebody can give sample code on this.

I think your problem is here:
keyword = engine.GetObject(Constants.WEBDAV_UKEN_PUB) as Keyword;
You are using the WEBDav URL of a publication, and then attempting a dynamic cast to Keyword. You can't cast a Publication to a Keyword, so the cast fails and your keyword variable is assigned null.
Using dynamic casts in this way is an easy way to fool yourself. The "As" keyword (C# keyword not Tridion keyword) should be used when you don't know at compile time what type you expect. If you know that you expect an item of type Keyword, then you should write:
keyword = (Keyword)engine.GetObject(Constants.WEBDAV_UKEN_PUB);
This way - when the cast fails, you'll get an exception that identifies the problem correctly.

In TOM.NET we cannot get an object and specify which pub to read it from, we need to modify the TcmUri to be in context.
So:
Repository context = (Repository)session.GetObject(WEBDAV_UKEN_PUB);
TcmUri keywordInContext = new TcmUri(keyword.Id.ItemId, keyword.Id.ItemType, context.Id.ItemId);
Keyword keyword = (Keyword)session.GetObject(keywordInContext);

Related

FSharp getting error: error FS0192 the anonymous record <>f__AnonymousType has not been generated in the pre-phase of generating this module

I'm trying to use Anonymous Records for the first time but getting an error on compile:
error FS0192 the anonymous record <>f__AnonymousType has not been generated in the pre-phase of generating this module
I'm using visual studio code on xubuntu and I don't see any errors in the IDE - so at least ionide seems to accept it; I only get the error when trying to run
dotnet version= 2.1.603
The offending code:
let load<'a> connectionString schemaDef (selector:obj) =
select<'a> connectionString schemaDef selector |> List.tryHead
let validateToken (clientToken:ClientWebToken) =
let loadedToken = liteOrm.load<WebToken> connectionString WebToken.SchemaDef {| TokenGuid= clientToken.TokenGuid |}
match loadedToken with
I can get around this by passing a typed record:
type TokenGuid = {
TokenGuid: Guid
}
let validateToken (clientToken:ClientWebToken) =
let loadedToken = liteOrm.load<WebToken> connectionString WebToken.SchemaDef { TokenGuid= clientToken.TokenGuid }
match loadedToken with
or by explicitly declaring the structure of the anonymous record (which I don't want to do):
let load<'a> connectionString schemaDef (selector: {| TokenGuid: Guid |}) =
select<'a> connectionString schemaDef selector |> List.tryHead
The issue I believe is that the compiler is unable to infer an appropriate type or convert the anonymous record to an obj.
Is there any way to pass the anonymous record as a generic object to a method and if so what type should the parameter be ?
This is currently a bug for passing an anonymous record to something accepting obj as its input parameter. This will be fixed. In the meantime, I recommend specifying the type explicitly or using type inference rather than the obj parameter type.

Convert a String to Call a Public Class ASP.NET VB

I have looked at this link and I cannot seem to get it to work
Creating a New control of the same type as another control that is already declared
I have also tried this from searches:
Dim ClassToCreate As String = "TestClass1.CountItems"
Dim myInstance = Activator.CreateInstance(Type.GetType(ClassToCreate), True)
Error is:
"Value cannot be null.
Parameter name: type"
Problem:
I have multiple classes and want to change which one is called based on a string.
(example is not correct of course)
Dim strClassToCall = "TestClass1.CountItems"
'then convert the string to the actual class so it can be called like this:
Dim strResult = TestClass1.CountItems(strSomeParameter)
Thanks for your help!
Based on the error message it sounds like your Type is not getting loaded properly as it is null. The method you are using will create the object like you need assuming you get the valid Type to pass to the activator. Is the type coming from an referenced DLL?
Here is one method you could use to get the type if just using the string representation is not working. This uses reflection to find the type:
// Sorry this is c# :)
System.Reflection.Assembly pAssembly = System.Reflection.Assembly.Load(
System.Reflection.Assembly.GetExecutingAssembly().
GetReferencedAssemblies().Single(a => a.Name.Equals("YourNamespace.ClassName")));
yourType = pAssembly.GetTypes().First(c => (c.FullName != null) &&
c.FullName.Equals("YourNamespace.ClassName"));
var yourObject = Activator.CreateInstance(yourType, true);

Accessing the query string value using ASP.NET

I have been trying to find the question to my answer but I'm unable to and finally I'm here. What I want to do is access the value passed to a webpage (GET, POST request) using asp.net. To be more clear, for example:
URL: http://www.foobar.com/SaleVoucher.aspx?sr=34
Using asp.net I want to get the sr value i.e 34.
I'm from the background of C# and new to ASP.NET and don't know much about ASP.NET.
Thanx.
Can you refer to this QueryString
Here he says how to access the query string using:
Request.Url.Query
That is not called a Header, but the Query String.
the object document.location.search will contain that and the javascript to get any query string value based on the key would be something like:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
code from other question: https://stackoverflow.com/a/901144/28004

XML validation error when updating Keyword metadata

Following on from my earlier question about creating Address Books (many thanks Peter!), I have a small throw-away console application doing just that and working great - but in addition I'm trying to update the metadata of a Keyword with the Item Id of the created Address Book.
Slightly shortened snippet ...
StaticAddressBook ab = new StaticAddressBook();
ab.Title = title;
ab.Key = key;
ab.Save();
// id is a correct Keyword TCM ID
Keyword k = tdse.GetObject(id, EnumOpenMode.OpenModeEdit);
if (k != null)
{
k.MetadataFields["addressbookid"].value[0] = ab.Id.ItemId;
k.Save(true);
}
I keep getting the following error on Save():
XML validation error. Reason: The element 'Metadata' in namespace
'uuid:2065d525-a365-4b45-b68e-bf45f0fba188' has invalid child element
'addressbookid' in namespace
'uuid:2065d525-a365-4b45-b68e-bf45f0fba188'. List of possible elements
expected: 'contact_us_email' in namespace
'uuid:2065d525-a365-4b45-b68e-bf45f0fba188'
But I know the Keyword has the correct Metadata assigned, (thats why I don't bother checking!). Shortened Tridion XML from a current keyword in question:
<tcm:Keyword>
<tcm:Data>
<tcm:MetadataSchemaxlink:type="simple"xlink:title="IP.Location.Metadata" xlink:href="tcm:49-2142-8" />
<tcm:Metadata>
<Metadata xmlns="uuid:2065d525-a365-4b45-b68e-bf45f0fba188">
<email>...</email>
<addressbookid>3</addressbookid>
<contact_us_email>...</contact_us_email>
<request_a_sample_email>...</request_a_sample_email>
<webinar_feedback_email>....</webinar_feedback_email>
</Metadata>
</tcm:Metadata>
<tcm:IsRoot>true</tcm:IsRoot>
</tcm:Data>
</tcm:Keyword>
Have I missed something can Keyword metadata not be updated in this way?
I guess I could look at the Core Service to update Keywords, but it seemed to to make sense to do everything within this application.
UPDATE
Order was key here, strangely!
The following code works:
ItemFields fields = k.MetadataFields;
System.Diagnostics.Debug.WriteLine(fields.Count);
string email = fields[1].value[1];
string contact = fields[3].value[1];
string request = fields[4].value[1];
string webinar = fields[5].value[1];
fields[1].value[1] = email;
fields[2].value[1] = ab.Id.ItemId;
fields[3].value[1] = contact;
fields[4].value[1] = request;
fields[5].value[1] = webinar;
k.Save(true);
Got caught out by the non-0-based index when getting/setting values and had to reassign existing fields back, in order.
Cheers
It seems that the order of the fields has changed in the Schema since that Component was created. At least the Schema expects contact_us_email in the position where you current have addressbookid.
There may be other changes, so I'd verify the order of fields in the Schema and make sure the Component(s) match, before you run your tool.

"Unexpected list type" exception when invoking ISessionAwareCoreService.GetList()

I am invoking the Tridion 2011 SP1 core service via the shipped client assembly. When I attempt to list the contents of a publication, I get an exception.
The code (simplified) looks like this:
ItemsFilterData filter = new Tridion.ContentManager.CoreService
.Client.RepositoryItemsFilterData.RepositoryItemsFilterData();
filter.ItemTypes = new ItemType[] {
ItemType.Folder,
ItemType.StructureGroup
};
filter.Recursive = false;
IEnumerable<IdentifiableObjectData> childItems = core.GetList("tcm:0-15-1", filter);
Note: the variable "core" refers to an ISessionAwareCoreService which I can successfully use to call, for example core.GetSystemWideList()
When .GetList is invoked, I get the following exception:
System.ServiceModel.FaultException`1 was unhandled
Message=Unexpected list type:
Tridion.ContentManager.Data.ContentManagement.RepositoryItemsFilterData.
What are the possible causes of this problem? Can you suggest a good general approach for interpreting this kind of message?
You can't get the direct children of a Publication using GetList. Instead you should just load the PublicationData with a client.Read and then access the RootFolder and RootStructureGroup on that.
PublicationData pub = (PublicationData)core.Read("tcm:0-1-1", new ReadOptions());
string rootFolder = pub.RootFolder.IdRef;
string rootSG = pub.RootStructureGroup.IdRef;
Alternatively you can call GetListXml with your RepositoryItemsFilterData and extract the items from the XML yourself.
XElement listResult = core.GetListXml(parent.ID, filter);

Resources