Cannot create list in SharePoint 2010 using Client Object Model - sharepoint-2010

I am trying to utilize SharePoint 2010 Client Object Model to create a List based on a custom template. Here's my code:
public void MakeList(string title, string listTemplateGUID, int localeIdentifier)
{
string message;
string listUrl;
ListTemplate template;
ListCreationInformation listInfo;
ListTemplateCollection templatesCollection;
try
{
listUrl = title.Replace(spaceChar, string.Empty);
templatesCollection = clientContext.Site.GetCustomListTemplates(clientContext.Web);
clientContext.Load(templatesCollection);
clientContext.ExecuteQuery();
foreach (ListTemplate t in templatesCollection)
{
if (t.InternalName == listTemplate)
{
template = t;
break;
}
}
listInfo = new ListCreationInformation();
listInfo.TemplateType = template.ListTemplateTypeKind;
//listInfo.TemplateFeatureId = template.FeatureId;
listInfo.Url = listUrl;
listInfo.Title = title;
listInfo.Description = string.Empty;
listInfo.QuickLaunchOption = QuickLaunchOptions.On;
site.Lists.Add(listInfo);
clientContext.ExecuteQuery();
return RetrieveList(title, listUrl);
}
catch (ServerException ex)
{
//...
}
}
A few unexpected things happen when this code is run:
My template is derived from the default document library template. Now, the code above does not create the document library based on my template - it creates the default document library instead.
If I uncomment the //listInfo.TemplateFeatureId = template.FeatureId; the code throws the ServerException error: "Cannot complete this action. Please try again."
If I place listInfo.TemplateFeatureId = template.FeatureId; before listInfo.TemplateType = template.ListTemplateTypeKind; the end result is the same as under item 1 - the default document library is created.
Could anyone please help me realize what am I doing wrong? Thanks.

Related

Document permissions Content Engine API

I'm trying to remove/add the groups from security of a document in FileNet using CPE API. I am able to remove wihtout any issues. However, when I try to add the groups that are missing, by inheriting from document class, groups get added without full permissions. For example, I remove "author" group and when I try to add the same group back, it does not have all the permissions.
Remove groups:
AccessPermissionList apl = doc.get_Permissions();
Iterator iter = apl.iterator();
while (iter.hasNext())
{
AccessPermission ap = (AccessPermission)iter.next();
if(ap.get_GranteeName().contains("group name")){
iter.remove();
}
}
doc.set_Permissions(apl);
doc.save(RefreshMode.NO_REFRESH);
Add groups:
DocumentClassDefinition docClassDef = Factory.DocumentClassDefinition.fetchInstance(os, classID, null);
AccessPermissionList docClassApl = docClassDef.get_Permissions();
Iterator docClassApliter = docClassApl.iterator();
for(Object obj : docClassApl)
{
AccessPermission ap = (AccessPermission)obj;
if(!apl.contains(ap)){
apl.add(ap);
}
}
doc.set_Permissions(apl);
doc.save(RefreshMode.NO_REFRESH);
RESOLVED:
Had to use DefaultInstanceSecurity rather than regular security as the permissions in both instances were different. So just updated the following line of code:
AccessPermissionList docClassApl = docClassDef.get_DefaultInstancePermissions();
You need to set AccessMask too. Like below:
AccessPermission ap;
ap.set_AccessMark ( new Integer (AccessLevel.FULL_CONTROL_DOCUMENT_AS_INT));
//AccessLevel.WRITE_DOCUMENT_AS_INT
//AccessLevel.MAJOR_VERSION_DOCUMENT_AS_INT
Version 5.2.0 onwards, AccessLevel is deprecated but you can give it a try. AccessRight is the replacement now. Refer this.
Update
public static void setPermissions(Document doc) throws IOException {
//In cpetarget.properties file
//cpetarget.security=Administrator:FULL_CONTROL,p8admin:MODIFY_PROPERTIES
InputStream input = new FileInputStream("cpetarget.properties");
java.util.Properties prop = new java.util.Properties();
prop.load(input);
List<String> strList = new ArrayList<String>(Arrays.asList(prop.getProperty("cpetarget.security").split(",")));
AccessPermissionList apl = doc.get_Permissions();
Iterator<AccessPermission> itr = apl.iterator();
List<AccessPermissionList> oldPermissionsList = new ArrayList<AccessPermissionList>();
oldPermissionsList.addAll(apl);
// Remove all your old permissions here
apl.removeAll(oldPermissionsList);
// Add all your new permissions here
try {
for (String str : strList) {
String[] strArray = str.split(":");
AccessPermission permission = Factory.AccessPermission.createInstance();
permission.set_GranteeName(strArray[0]);
permission.set_AccessType(AccessType.ALLOW);
permission.set_InheritableDepth(new Integer(0));
//permission.set_InheritableDepth(new Integer(0)); // this object only
//permission.set_InheritableDepth(new Integer(-1));this object and all children
//permission.set_InheritableDepth(new Integer(1)); this object and immediate children
if (strArray[1].equalsIgnoreCase("FULL_CONTROL")) {
permission.set_AccessMask(new Integer(AccessLevel.FULL_CONTROL_DOCUMENT_AS_INT));
//permission.set_AccessMask(AccessRight.MAJOR_VERSION_AS_INT);
}
if (strArray[1].equalsIgnoreCase("READ_ONLY")) {
permission.set_AccessMask(new Integer(AccessLevel.VIEW_AS_INT));
}
if (strArray[1].equalsIgnoreCase("MODIFY_PROPERTIES")) {
permission.set_AccessMask(new Integer(AccessLevel.WRITE_DOCUMENT_AS_INT));
}
if (strArray[1].equalsIgnoreCase("MAJOR_VERSIONING")) {
permission.set_AccessMask(new Integer(AccessLevel.MAJOR_VERSION_DOCUMENT_AS_INT));
}
AccessPermissionList permissions = doc.get_Permissions();
permissions.add(permission);
doc.set_Permissions(permissions);
doc.save(RefreshMode.REFRESH);
System.out.println("Done");
}
} catch (Exception e) {
e.printStackTrace();
}
}

Rendering #Html.Action("actionName","controllerName") at runtime , fetching from database in MVC4

My requirement is to fetch html data from database and render it on view. But if that string contains #Html.Action("actionName","controllerName"), i need to call perticular controller action method also.
I am rendering my html on view using #Html.Raw().
Eg: Below is the html string stored in my database
'<h2> Welcome To Page </h2> <br/> #Html.Action("actionName", "controllerName")'
So when it render the string, it execute mentioned controller and action too.
Any help will be appreciated.
You can try RazorEngine to allow string template in razor executed.
For example, sample code from the project site http://antaris.github.io/RazorEngine/:
using RazorEngine;
using RazorEngine.Templating; // For extension methods.
string template = "Hello #Model.Name, welcome to RazorEngine!";
var result =
Engine.Razor.RunCompile(template, "templateKey", null, new { Name = "World" });
But there is one catch, Html and Url helpers are defined in the Mvc framework, hence it is not supported by default.
I will suggest you try to create your template by passing model so that you don't have to use #Html.Action.
If you can not avoid it, then there is possible a solution suggested by another so answer https://stackoverflow.com/a/19434112/2564920:
[RequireNamespaces("System.Web.Mvc.Html")]
public class HtmlTemplateBase<T>:TemplateBase<T>, IViewDataContainer
{
private HtmlHelper<T> helper = null;
private ViewDataDictionary viewdata = null;
public HtmlHelper<T> Html
{
get
{
if (helper == null)
{
var writer = this.CurrentWriter; //TemplateBase.CurrentWriter
var context = new ViewContext() { RequestContext = HttpContext.Current.Request.RequestContext, Writer = writer, ViewData = this.ViewData };
helper = new HtmlHelper<T>(vcontext, this);
}
return helper;
}
}
public ViewDataDictionary ViewData
{
get
{
if (viewdata == null)
{
viewdata = new ViewDataDictionary();
viewdata.TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = string.Empty };
if (this.Model != null)
{
viewdata.Model = Model;
}
}
return viewdata;
}
set
{
viewdata = value;
}
}
public override void WriteTo(TextWriter writer, object value)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (value == null) return;
//try to cast to RazorEngine IEncodedString
var encodedString = value as IEncodedString;
if (encodedString != null)
{
writer.Write(encodedString);
}
else
{
//try to cast to IHtmlString (Could be returned by Mvc Html helper methods)
var htmlString = value as IHtmlString;
if (htmlString != null) writer.Write(htmlString.ToHtmlString());
else
{
//default implementation is to convert to RazorEngine encoded string
encodedString = TemplateService.EncodedStringFactory.CreateEncodedString(value);
writer.Write(encodedString);
}
}
}
}
Then you have to use HtmlTemplateBase (modified base on https://antaris.github.io/RazorEngine/TemplateBasics.html#Extending-the-template-Syntax):
var config = new TemplateServiceConfiguration();
// You can use the #inherits directive instead (this is the fallback if no #inherits is found).
config.BaseTemplateType = typeof(HtmlTemplateBase<>);
using (var service = RazorEngineService.Create(config))
{
string template = "<h2> Welcome To Page </h2> <br/> #Html.Action(\"actionName\", \"controllerName\")";
string result = service.RunCompile(template, "htmlRawTemplate", null, null);
}
in essence, it is telling the RazorEngine to use a base template where mvc is involved, so that Html and Url helper can be used.

Copying sitecore rendering to new template programmatically using renderingDefinition.ItemId?

I have a custom sitecore button which changes the template of the current item, simple enough.
However as part of this I'm trying to also migrate the renderings of the old layout to a new layout if it's of a certain sublayout type by ItemId. However the ItemId that is returned is always null, the only value I get back from the RenderingDefinition is the UniqueId.
What am I doing wrong?
I have used this blog post as a guide.
The Code
public class ConvertToNewTemplateCommand : Command
{
protected void Run(ClientPipelineArgs args)
{
if (!SheerResponse.CheckModified())
return;
Item item = Context.ContentDatabase.Items[args.Parameters["id"]];
if (args.IsPostBack)
{
if (args.Result == "yes")
{
//Get current layout details
var originalLayoutXml = item[FieldIDs.LayoutField];
//Get new template
TemplateItem hubTemplate = Context.ContentDatabase.GetTemplate("some guid...");
//Change template
item.ChangeTemplate(hubTemplate);
//Reset laytout
ResetLayout(item);
//Get reset layout
var newLayoutXml = item[FieldIDs.LayoutField];
//Add all the module containers to the new layout in the central column
MoveModuleContainers(item, originalLayoutXml, newLayoutXml);
}
}
}
private void MoveModuleContainers(Item item, string oldXml, string newXml)
{
var oldLayout = LayoutDefinition.Parse(oldXml);
var newLayout = LayoutDefinition.Parse(newXml);
bool updated = false;
var oldRenderings = (oldLayout.Devices[0] as DeviceDefinition).Renderings;
var newRenderings = (newLayout.Devices[0] as DeviceDefinition).Renderings;
foreach (RenderingDefinition rendering in oldRenderings)
{
// Here is where the rendering.ItemID is always null
if (rendering != null && !String.IsNullOrEmpty(rendering.ItemID) && new Guid(rendering.ItemID) == new Guid("matching guid..."))
{
rendering.Placeholder = "middlecolumn";
newRenderings.Add(rendering);
updated = true;
}
}
if (updated)
{
// Save item...
}
}
}
I got onto Sitecore support in the end which informed me that I should use:
Sitecore.Data.Fields.LayoutField.GetFieldValue(item.Fields[Sitecore.FieldIDs.LayoutField])
instead of:
item[FieldIDs.LayoutField]
to get the items layoutField correctly. This results in the rendering values being parsed correctly and as they say the rest is history.

Override DbConnectionAttributes in Crystal Report Viewer when using ADO.NET (XML) connection

I have a .net form with crystal report viewer on it. The report I am trying to load in it was made with a connection of type ADO.Net(xml) with hardcoded path to the file name (.dll in this case) that returns back a dataset. My problem is that the path to that dll differs based on the installation path of the application. So i need to override it in code but i am not sure how to do it. Here is the code i am using:
Dim conInfo As New ConnectionInfo()
conInfo.Type = CrystalDecisions.Shared.ConnectionInfoType.CRQE
conInfo.Attributes.Collection.Add(New NameValuePair2("Database DLL", "crdb_adoplus.dll"))
conInfo.Attributes.Collection.Add(New NameValuePair2("QE_DatabaseName", ""))
Dim dba As New DbConnectionAttributes
dba.Collection.Add(New NameValuePair2("Class Name", "class name in that dll"))
dba.Collection.Add(New NameValuePair2("DataSet Names", "method in the class"))
dba.Collection.Add(New NameValuePair2("File Path", "path to dll.dll"))
conInfo.Attributes.Collection.Add(New NameValuePair2("QE_DatabaseType", "ADO.NET (XML)"))
conInfo.Attributes.Collection.Add(New NameValuePair2(DbConnectionAttributes.QE_LOGON_PROPERTIES, dba))
CrystalReportViewer1.ParameterFieldInfo = paramFields
CrystalReportViewer1.ReportSource = ReportFileName
Crystal report viewer shows up and asks for the login information which is wrong.
Any help would be appreciated.
Might be a bit old but here is a working solution for C# and Crystal Report 13.0.28.
Can't tell if modification of the other attributes in InitTable are really necessary. Maybe they won't be set to these defaults in a future version of CR.
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
private void PrintMe()
{
using (ReportDocument rep = new ReportDocument())
{
//Open report
rep.Load(sReport, OpenReportMethod.OpenReportByTempCopy);
NameValuePair2 nvp2 = new NameValuePair2("File Path ", sFullFileName); //Space after "File Path " is important! The LogonProperties have defined it as such
InitTables(rep, nvp2);
rep.Refresh();
if (sReportPdf == null)
{
rep.PrintOptions.PaperSource = printerSettings.PaperSource;
rep.PrintOptions.PaperOrientation = printerSettings.PaperOrientation;
rep.PrintOptions.PaperSize = printerSettings.PaperSize;
rep.PrintOptions.PrinterName = printerSettings.PrinterName;
rep.PrintOptions.ApplyPageMargins(printerSettings.PageMargins);
rep.PrintToPrinter(printerSettings.NumCopies, true, 1, 9999);
}
else
{
rep.ExportToDisk(ExportFormatType.PortableDocFormat, sReportPdf);
}
}
}
private void InitTables(ReportDocument rep, NameValuePair2 filePath)
{
foreach (Table table in rep.Database.Tables)
{
var collection = table.LogOnInfo.ConnectionInfo.Attributes.Collection;
InitTableCollections(collection, "Database DLL", "crdb_adoplus.dll"); //same as default
InitTableCollections(collection, "QE_DatabaseName", ""); //same as default
InitTableCollections(collection, "QE_DatabaseType", "ADO.NET (XML)"); //same as default
InitTableCollections(collection, "QE_ServerDescription", "items"); //default: invoice
InitTableCollections(collection, "QE_SQLDB", false); //same as default
InitTableCollections(collection, "SSO_Enabled", false); //same as default
InitTableCollections(table.LogOnInfo.ConnectionInfo.LogonProperties, filePath);
table.ApplyLogOnInfo(table.LogOnInfo);
}
try
{
foreach (ReportDocument subReportDocument in rep.Subreports)
InitTables(subReportDocument, filePath);
}
catch (NotSupportedException)
{
//thrown when trying to enumerate rep.Subreports at a certain depth
}
}
private void InitTableCollections(NameValuePairs2 collection, string key, object value)
{
if (collection.ContainsKey(key))
collection.Set(key, value);
else
collection.Add(new NameValuePair2(key, value));
}
private void InitTableCollections(NameValuePairs2 collection, NameValuePair2 nvp)
{
if (collection.ContainsKey(nvp.Name))
collection.Set(nvp.Name, nvp.Value);
else
collection.Add(new NameValuePair2(nvp.Name, nvp.Value));
}

Exception in Entity Framework: Error 0194: All artifacts loaded

This is a c#/asp.net project. The full error message I get is:Error 0194: All artifacts loaded into the item collection must have the same version. Multiple versions were encountered.
This project was started as a 3.5 and upgraded to 4.0. When I try to test any of the methods I get the error that I posted in the subject line. I am going to include the actual lines that it throws the exception on. If there is anything in people need to see to try to help let me know and I post it as well. Any help will be appreciated, I am having no luck with this.
/// <summary>
/// Initializes a new SFBExternalPaymentsEntities object using the connection string found in the 'SFBExternalPaymentsEntities' section of the application configuration file.
/// </summary>
public SFBExternalPaymentsEntities() : base("name=SFBExternalPaymentsEntities", "SFBExternalPaymentsEntities")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
/// <summary>
/// Initialize a new SFBExternalPaymentsEntities object.
/// </summary>
public SFBExternalPaymentsEntities(string connectionString) : base(connectionString, "SFBExternalPaymentsEntities")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
/// <summary>
/// Initialize a new SFBExternalPaymentsEntities object.
/// </summary>
public SFBExternalPaymentsEntities(EntityConnection connection) : base(connection, "SFBExternalPaymentsEntities")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
#endregion
Added a method calling the constructor.
public static CreditCardResponse AuthCapture(CreditCard newCC)
{
ACHResponse validateResponse = CreditCard.Validate(newCC);
if (validateResponse.Status == "Accepted")
{
Profile currentProfile = new Profile();
currentProfile = ProfilesGateWay.GetByID(newCC.ProfileID);
CreditCardTransaction newCCTransaction = CreateCreditCardTransaction(newCC, currentProfile);
ServiceClient client = new ServiceClient();
CreditCardTransactionResponse cctResponse = client.CreditCardAuthorizeAndCapture(newCCTransaction);
client.Close();
CreditCardResponse ccResponse = CreateCCResponse(cctResponse);
if (ccResponse.ResponseCode == 1)
{
int authAVS = ConvertAVStoInt(ccResponse.AVSResponse);
int appAVS = ConvertAVStoInt(newCC.AVLevel);
bool isAVSPass = CompareAVS(authAVS, appAVS);
if (isAVSPass == false)
{
ccResponse.ResponseCode = 0;
ccResponse.ResponseReasonCode = 99;
ccResponse.ResponseText = "Did not meet your AVS requirements";
return ccResponse;
}
else
{
int newCCID = CreateCreditCardRecord(newCC, currentProfile, cctResponse, "Captured", "Auth_Capture");
CreditCardRecord updateCC = CreditCardRecordsGateWay.GetByID(newCCID);
updateCC.CaptureOn = DateTime.Now;
CreditCardRecordsGateWay.Update(updateCC);
return ccResponse;
}
}
else
{
return ccResponse;
}
}
CreditCardResponse newCCResponse = new CreditCardResponse();
newCCResponse.ResponseCode = 0;
newCCResponse.AchResponse = validateResponse;
return newCCResponse;
}
public static CreditCardResponse PriorAuthCapture(CreditCard newCC)
{
CreditCardRecord ccRecord = CreditCardRecordsGateWay.GetByCCGateWayID(newCC.CreditCardTransactionID);
ServiceClient client = new ServiceClient();
CreditCardTransaction ccTransaction = client.CreditCardGetTransactionById(ccRecord.CCGatewayID);
CreditCardTransactionResponse cctResponse = client.CreditCardPriorAuthorizationCapture(ccTransaction);
if (cctResponse.ResponseCode == 1)
{
ccRecord.Status = "Captured";
ccRecord.CaptureOn = DateTime.Now;
}
CreditCardResponse ccResponse = CreateCCResponse(cctResponse);
return ccResponse;
}
protected static int CreateCreditCardRecord(CreditCard newCC, Profile currentProfile, CreditCardTransactionResponse cctResponse, string status, string transactionType)
{
CreditCardRecord newCCRecord = new CreditCardRecord();
newCCRecord.Address = newCC.Address;
newCCRecord.AddressVerificationLevel = newCC.AVLevel;
newCCRecord.Amount = newCC.Amount;
newCCRecord.CardCode = newCC.CardCode;
newCCRecord.CardNumber = newCC.CardNumber;
newCCRecord.CCGatewayID = cctResponse.CreditCardTransactionID;
newCCRecord.City = newCC.City;
newCCRecord.CompanyName = newCC.CompanyName;
newCCRecord.CreateBy = currentProfile.ACHCompanyName;
newCCRecord.CreateOn = DateTime.Now;
newCCRecord.Description = newCC.Description;
newCCRecord.Expiration = newCC.Expiration;
newCCRecord.FirstName = newCC.FirstName;
newCCRecord.LastName = newCC.LastName;
newCCRecord.Profile.ProfileID = currentProfile.ProfileID;
newCCRecord.State = newCC.State;
newCCRecord.Status = status;
newCCRecord.TransactionType = transactionType;
newCCRecord.Zip = newCC.Zip;
return CreditCardRecordsGateWay.Insert(newCCRecord);
}
You have just posted the constructors to your SFBExternalPaymentsEntities class, but you seem to say that you get an exception when you call a method that returns a collection of entities, which makes send with the exception message you are getting. The chances are the problem lies within the method you are calling, or in the code calling it rather than in the constructor code you have posted. Can you post some more relevent code or explain how the code you have posted relates to the exception.
I encountered the same problem when i updated one of my projects from .net 4.0 to 4.5, the reason probably was because there was another .edmx file in an other project that was referenced in the target project.
Solution to issue : Updated the other project that was referenced and contained .edmx file to .net 4.5 and then, Right-Clicked on every .edmx files in these 2 projects and then selected 'Run Custom Tool'
It worked for me, hope that it works for everyone reading this article