SharePoint Web Services - Updating ContentType field Required property? - web-services

I've been trying to programmatically reproduce the behavior of editing a Content Type's field properties in the SharePoint site management screen and selecting the "Required" radio button with no sucess using the WSS 3.0 web service's Webs.asmx "UpdateContentType" method.
The first difficulty was the issue with the MSDN documentation that said fields should be of a FieldRef type when in fact they need to be of a Field type (reference). Adding fields and deleting fields works fine after the fix, but updating fields seems to not function at all. (It should also be noted that I followed the recommendation on the previous link to use Method="2" for updating fields but it changes nothing, and using Method values other than 1 for adding or other than 3 for deleting also function correctly).
Here's the web service call (slightly modified with strings instead of XmlNode objects for readability):
SharePointWebServices.Webs webService = new SharePointWebServices.Webs();
webService.Url = "http://mysharepointserver/site";
webService.UseDefaultCredentials = true;
webService.UpdateContentType(
#"0x01005A089D9EC8A382458FB1F6C72096D52A",
#"<ContentType />",
#"<Fields />",
#"<Fields><Method ID=""1""><Field Name=""SomeField"" ID=""{8a4803c4-6545-4a7a-804d-237eebff0ce3}"" Required=""TRUE"" Hidden=""FALSE"" ReadOnly=""FALSE"" PITarget="""" PIAttribute="""" PrimaryPIAttribute="""" Aggregation="""" Node="""" /></Method></Fields>",
#"<Fields />");
After the call, the field is still Required="FALSE".
A quick look into the stssoap.dll assembly indicates that the "Required" property is apparently ignored during the update process. Is this normal behavior? If so, what is the recommended method for programmatically changing the "Required" field from client code (not executing on the SharePoint server)?
Any help would be greatly appreciated.

I've investigated this and found the same thing. I also tried adding the attribute Cmd="Update" to the Method element without success. This example of how to use UpdateContentType was helpful too.
I don't believe you will be able to do this with the out-of-the-box SharePoint services. You've verified from looking at stssoap.dll that this doesn't appear to work correctly. Another 'client'-style option is to use RPC methods but none appear to provide functionality for content types at all.
The web services are particularly frustrating because this type of not-so-edge case regularly comes up. It is very rare that I consider using them because of the time wasting involved with their limitations.
Do you have any option of deploying custom code to the server? You could develop this functionality using the object model and wrap it in your own custom web service (there is a walkthrough here) quite easily.
Here is an example adapted from Gabe Wishnie that does what you require:
SPContentType myContentType = myWeb.ContentTypes["myContentType"];
string internalName = myContentType.Fields["fieldToUpdate"].InternalName;
myContentType.FieldLinks[internalName].Required = false;
myContentType.Update(true);
Sorry this isn't more helpful but it's a common story when using the WSS 3.0 / SharePoint 2007 web services.

Related

MURA CMS: how to add a page programmatically

So, what can I say? How do I go about adding a page programmatically in MURA CMS? Preferably version 6.1.
I am building a plugin that needs to create a couple of pages in the Site Manager. I want to add this routine in the 'install' method of the 'plugin/plugin.cfc' component.
I have been unable to find any pointers to this on line, which, perhaps, means this particular issue cannot be resolved. But, I live in hope.
Thanks people, in advance, for any help on this one.
When you add content to Mura, the key is that you'll need to know the parentid of where you wish the new content item(s) to live. Other than that, Mura offers an easy way perform CRUD operations on content items. You can read more about it at http://docs.getmura.com/v6/back-end/base-mura-objects-beans/loading-beans/ (based on the version you've specified). I'd also like to point out that the documentation has been greatly expanded in the latest version which can be found at http://docs.getmura.com/v7/mura-developers/mura-beans-objects/common-bean-objects/content-bean/. While the concepts and syntax still apply to older version, some newer methods for working with Mura content objects have been added since v6.1. I also highly recommend upgrading soon, as v7.1 is about to be released as well (as of Feb. 2018).
That said, the only two required fields/attributes are title and parentid. Here's the basic code for being able to do what you need:
// load the parent content item
parentBean = $.getBean('content').loadBy(title='Home');
// you may want to verify the `parentBean` actually exists before proceeding
if ( parentBean.getIsNew() ) {
Throw(message='parentBean does NOT exist!');
}
// v6.1 syntax
newBean = $.getBean('content')
.setValue('title', 'Some Title')
.setValue('parentid', parentBean.getContentID())
.save();
// v7.0+ syntax
newBean = $.getBean('content')
.set('title', 'Some Title')
.set('parentid', parentBean.get('contentid'))
.save();
// after saving, you can check for errors
if ( !StructIsEmpty(newBean.getErrors()) ) {
WriteDump(var=newBean.getErrors(), abort=true);
}
You could clearly set other attributes (as defined in the earlier links) as well, if desired.
Cheers!

Can a Custom DataProvider class expose Custom Templates?

I am currently in the process of writing a custom DataProvider. Using the Intergrate External Data documentation.
I've managed to show the external data in the Sitecore back end. However whenever I try to view the data in the items I created, I am getting an error
Null ids are not allowed. <br> Parameter name: displayName
There seems to be precious little on the subject on how to create a custom DataProvider on the Sitecore Developer Network.
The example on their website seems to only show how to import a SINGLE item into a static database. However I am simply trying to merge some items into the hierarchy and I can't find any useful documentation.
It seems that one of your methods that should return an ID doesn't. It might be GetChildIds and/or GetParentId.
Nick Wesselman wrote a good article about it gathering all the information including an example on the Marketplace. I think that is your best start. You can read it here.
Turns out I needed to include at the very least, the Fields->Section->Template in the GetParent method. To be on the safe side I included the Fields/Sections/Templates into my implementations of
GetChildIDs
GetItemDefinition
GetParentID
It wasn't obvious that this was the case, since I had in fact implemented the GetTemplates method correctly, and I had expected that should be enough.

Getting error while reading salesforce custom field type Rich Textarea

I am using salesforce.cfc (downloded from Riaforge) to integrate coldfusion with salesforce.
<cfset latestProductList = salesforce.queryObject("SELECT Id, Name, Description__c, Price__c, ProductImage__c FROM Product__c") />
I have created one custom object named "Product__c". This object have one custom field "ProductImage__c" type "Rich TextArea". When i an trying to get product without this custom field it is run, but when i am trying to get product with this field i am getting below error:
"INVALID_FIELD: Name, Description__c, Price__c, ProductImage__c FROM Product__c ^ ERROR at Row:1:Column:44 No such column 'ProductImage__c' on entity 'Product__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. "
But i have this field. attached screen image of salesforce below.
Thanks,
Arun
A quick look at Salesforce CFC shows that it hasn't been updated in a while. The file SalesForce.cfc is pointing at:
https://www.salesforce.com/services/Soap/u/11.1
That's version 11.1 of the API, which is quite old and is long before rich text fields came into existence.
You might be able to fix this issue by simply updating the reference in SalesForce.cfc to the latest version of the API by changing
https://www.salesforce.com/services/Soap/u/11.1
to
https://www.salesforce.com/services/Soap/u/28.0
in that file, although there's a pretty good likelihood that that will break something else, since version 28.0 will have lots of new stuff that SalesForce.cfc is not coded to handle.
In any case, your problem is in fact the API version that you're using. In cases like this, when a field type did not exist as of a certain API version, then that field is invisible for that version. In your case, your rich text field is invisible for your API version, 11.1.

Read AICC Server response in cross domain implementation

I am currently trying to develop a web activity that a client would like to track via their Learning Management System. Their LMS uses the AICC standard (HACP binding), and they keep the actual learning objects on a separate content repository.
Right now I'm struggling with the types of communication between the LMS and the "course" given that they sit on two different servers. I'm able to retreive the sessionId and the aicc_url from the URL string when the course launches, and I can successfully post values to the aicc_url on the LMS.
The difficulty is that I can not read and parse the return response from the LMS (which is formatted as plain text). AICC stipulates that the course start with posting a "getParam" command to the aicc_url with the session id in order to retrieve information like completion status, bookmarking information from previous sessions, user ID information, etc, all of which I need.
I have tried three different approaches so far:
1 - I started with using jQuery (1.7) and AJAX, which is how I would typically go about a same-server implementation. This returned a "no transport" error on the XMLHttpRequest. After some forum reading, I tried making sure that the ajax call's crossdomain property was set to true, as well as a recommendation to insert $.support.cors = true above the ajax call, neither of which helped.
2 & 3 - I tried using an oldschool frameset with a form in a bottom frame which would submit and refresh with the returned text from the LMS and then reading that via javascript; and then a variation upon that using an iFrame as a target of an actual form with an onload handler to read and parse the contents. Both of these approaches worked in a same-server environment, but fail in the cross-domain environment.
I'm told that all the other courses running off the content repository bookmark as well as track completion, so obviously it is possible to read the return values from the LMS somehow; AICC is pitched frequently as working in cross-server scenarios, so I'm thinking there must be a frequently-used method to doing this in the AICC structure that I am overlooking. My forum searches so far haven't turned up anything that's gotten me much further, so if anyone has any experience in cross-domain AICC implementations I could certainly use recommendations!
The only idea I have left is to try setting up a PHP "relay" form on the same server as the course, and having the front-end page send values to that, and using the PHP to submit those to the LMS, and relay the return text from the LMS to the front-end iframe or ajax call so that it would be perceived as being within the same domain.... I'm not sure if there's a way to solve the issue without going server-side. It seems likely there must be a common solution to this within AICC.
Thanks in advance!
Edits and updates:
For anyone encountering similar problems, I found a few resources that may help explain the problem as well as some alternate solutions.
The first is specific to Plateau, a big player in the LMS industry that was acquired by Successfactors. It's some documentation that provide on setting up a proxy to handle cross-domain content:
http://content.plateausystems.com/ContentIntegration/content/support_files/Cross-domain_Proxlet_Installation.pdf
The second I found was a slide presentation from Successfactors that highlights the challenge of cross-domain content, and illustrates so back-end ideas for resolving it; including the use of reverse proxies. The relevant parts start around slide 21-22 (page 11 in the PDF).
http://www.successfactors.com/static/docs/successconnect/sf/successfactors-content-integration-turley.pdf
Hope that helps anyone else out there trying to resolve the same issues!
The answer in this post may lead you in the right direction:
Best Practice: Legitimate Cross-Site Scripting
I think you are on the right track with setting up a PHP "relay." I think this is similar to choice #1 in the answer from the other post and seems to make most sense with what you described in your question.

Retrieving Enterprise Project Types using Project Server Interface

I am currently building an app to programatically create projects in Microsoft Project Server using the web services exposed through the Project Server Interface (PSI).
I am able to create a project with an Enterprise Project Type using the QueueCreateProject method, however, I need to specify the GUID of the EPT which I don't want to hard code into the code.
Is there another web service or way to get the GUID of a specific EPT found by its name?
Also, can the same be done for custom fields in the same way?
I think what you're looking for is PSI Filter parameters. Check out this post for an example of retrieving the Guid of a custom field.
Really, I think the key is setting the filter criteria:
cfFilter.Criteria = new PSLibrary.Filter.FieldOperator(equal, nameColumn, customFieldName);
Where nameColumn is cfDataSet.CustomFields.MD_PROP_NAMEColumn.ColumnName and customFieldName is a value you pass in.
If you are like me, you want to do this for a lot of fields. I used a filter to query all the field names and MD_PROP_UID's and then just put it in a hashtable so I don't have to keep making PSI calls.
Disclaimer: I use 2007 but I'm assuming it is mostly the same for custom fields (not for the EPT part which I didn't include).
Here is an answer: https://stackoverflow.com/a/12267251/1594383
In short: the methods are available from Workflow service.