How can i get the package component XML as TBB output - tridion

I am trying to get the default Package Component XML as the TBB Output. I am using the below code :
public void Transform(Engine engine, Package package)
{
XmlDocument packagebasexml = new XmlDocument();
packagebasexml.LoadXml(package.GetByName("Component"));
package.PushItem(Package.OutputName, package.CreateXmlDocumentItem(ContentType.Xml,packagebasexml));
}
but i am not able to get, kindly give any suggestion/changes.

The following .Net TBB should copy the Component Package Item XML to the Template output:
using System.Xml;
using Tridion.ContentManager.Templating;
using Tridion.ContentManager.Templating.Assembly;
namespace SDLTridion.Templating
{
[TcmTemplateTitle("Get Component Input as Output")]
class GetComponentInputAsOutput: ITemplate
{
public void Transform(Engine engine, Package package)
{
Item componentItem = package.GetByName(Package.ComponentName);
XmlDocument componentItemXml = componentItem.GetAsXmlDocument();
Item componentItemXmlAsString = package.CreateStringItem(ContentType.Text, componentItemXml.OuterXml);
package.PushItem(Package.OutputName, componentItemXmlAsString);
}
}
}

Did you try with .Content property. Also may I know what you want to achieve by pushing XML to package.
public void Transform(Engine engine, Package package)
{
XmlDocument packagebasexml = new XmlDocument();
packagebasexml.LoadXml(package.GetByName("Component").Content.OuterXml);
package.PushItem(Package.OutputName, package.CreateXmlDocumentItem(ContentType.Xml,packagebasexml));
}
Another way to get full xml
Item m_XmlInput = m_Package.GetByName(package.GetByName("Component"));
XmlTextReader input = new XmlTextReader(new StringReader(m_XmlInput.GetAsString()));

Related

How do I get ShellSettingsManager in an async extension to VS2019?

I wanted to create a small extension to add a list of External Tools to VS2019. A quick search brought up what appeared to be perfect example code at https://learn.microsoft.com/en-us/visualstudio/extensibility/writing-to-the-user-settings-store?view=vs-2019. This adds a command to invoke Notepad, so I thought with a few edits, my work was done.
However, this example is written as a synchronous extension, which is deprecated, so I tried putting the code intended for MenuItemCallBack into the Execute method of the extension, but the line
SettingsManager settingsManager = new ShellSettingsManager(ServiceProvider);
fails to compile, because ServiceProvider is now type IAsyncServiceProvider and the ShellSettingsManager constructor wants an argument of type IServiceProvider.
As far as I can tell, ShellSettingsManager is still the way to access the Settings Store, but all the examples I could find all refer to putting code in MenuItemCallback (as well as being several years old) so are for synchronous extensions.
So, can someone point me to the recommended way to get access to the settings store in an asynchronous extension?
The ShellSettingsManager constructor takes either an IServiceProvider interface or an IVsSettings interface. Given your AsyncPackage derived object implements IServiceProvider, you should be able to just pass it in as the argument to your constructor. The following quick demo package worked for me:
using System;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft;
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.Settings;
using Task = System.Threading.Tasks.Task;
namespace UserSettingsDemo
{
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(UserSettingsDemoPackage.PackageGuidString)]
[ProvideMenuResource("Menus.ctmenu", 1)]
public sealed class UserSettingsDemoPackage : AsyncPackage
{
public const string PackageGuidString = "cff6cdea-21d1-4736-b5ea-6736624e718f";
public static readonly Guid CommandSet = new Guid("dde1417d-ae0d-46c4-8c84-31883dc1a835");
public const int ListExternalToolsCommand = 0x0100;
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
OleMenuCommandService commandService = await GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
Assumes.Present(commandService);
var menuItem = new MenuCommand(OnListExternalTools, new CommandID(CommandSet, ListExternalToolsCommand));
commandService.AddCommand(menuItem);
}
private void OnListExternalTools(object sender, EventArgs e)
{
ShellSettingsManager settingsManager = new ShellSettingsManager(this);
WritableSettingsStore userSettingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);
int toolCount = userSettingsStore.GetInt32("External Tools", "ToolNumKeys");
for (int i = 0; i < toolCount; i++)
{
string tool = userSettingsStore.GetString("External Tools", "ToolCmd" + i);
VsShellUtilities.ShowMessageBox(this, tool, "External Tools", OLEMSGICON.OLEMSGICON_INFO,
OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
}
}
}
}
Sincerely

ConvertApi NuGet Package Error: Could not install package 'ConvertApi 2.7.0'

I am Adding ConvertApi nuget package to Convert PDF to Doc file,
But getting below Error
Could not install package 'ConvertApi 2.7.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.6.1', but the package does not contain any assembly references or content files that are compatible with that framework.
Note:
You can Suggesst some other API's as well to achieve the above task.
The ConvertApi 2.7.0 NuGet package is .NET Core 2 version library and can be installed on .NET 4.7 or higher. However, you can use plain C# implementation to call ConvertAPI REST API, the example below use WebClient to send an MS Word file for conversion to PDF document.
using System;
using System.Net;
using System.IO;
class MainClass {
public static void Main (string[] args) {
const string fileToConvert = "test.docx";
const string fileToSave = "test.pdf";
const string Secret="";
if (string.IsNullOrEmpty(Secret))
Console.WriteLine("The secret is missing, get one for free at https://www.convertapi.com/a");
else
try
{
Console.WriteLine("Please wait, converting!");
using (var client = new WebClient())
{
client.Headers.Add("accept", "application/octet-stream");
var resultFile = client.UploadFile(new Uri("http://v2.convertapi.com/convert/docx/to/pdf?Secret=" + Secret), fileToConvert);
File.WriteAllBytes(fileToSave, resultFile );
Console.WriteLine("File converted successfully");
}
}
catch (WebException e)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
Console.WriteLine("Body : {0}", new StreamReader(e.Response.GetResponseStream()).ReadToEnd());
}
}
}

How do I extract the output of Style or Javascript Bundle in ASP.NET

I am working on a single page app that uses a CSS bundle in a .cshtml file as shown below:
#Styles.Render("~/content/css/bundle-css")
However, to improve the loading performance of the site, I would like to embed the entire CSS that was bundled and minified into my .cshtml file. So I would like to convert the code above to look like:
#Html.GetInternalCss("~/content/css/bundle-css");
Where GetInternalCss is an extension method that will take the css virtual path and output an internal css. The code is shown below:
public static MvcHtmlString GetInternalCss(this HtmlHelper html, string styleBundleVirtualPath)
{
//TODO:
var bundledCss = "How do I extract the css from the virtual path?";
var internalCss = string.Format("<style>{0}</style>", bundledCss);
return new MvcHtmlString(internalCss);
}
I know the bundled css is in memory somewhere. I just need to know how to get it out. Thanks for all your help.
I may have answered my own question with the code below:
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Web.Mvc;
using System.Web.Optimization;
namespace SomeNameSpace
{
public static class HtmlHelpExtensions
{
private static readonly IDictionary<string,string> InternalCssCache = new ConcurrentDictionary<string, string>();
public static MvcHtmlString GetInternalCss(this HtmlHelper html, string styleBundleVirtualPath)
{
string internalCss = null;
if (InternalCssCache.TryGetValue(styleBundleVirtualPath, out internalCss))
return new MvcHtmlString(internalCss);
//download the css
var relativeUrl = Styles.Url(styleBundleVirtualPath);
var url = html.ViewContext.HttpContext.Request.Url + relativeUrl.ToString().Trim('/');
var webClient = new WebClient();
var css = webClient.DownloadString(url);
internalCss = string.Format("<style>{0}</style>", css);
InternalCssCache[styleBundleVirtualPath] = internalCss;
return new MvcHtmlString(internalCss);
}
}
}

Unable to create component using Coreservice

I am trying to create component using coreservice using the below code, and when i execute the exe, am getting the error "unable to find the uuid:""64c7e56a-161d-4698-a76b-7fd96227948d:Content".
I have opened the schema which am linking to this component, and i seen this UUID over there also.
as of now am just trying to create a component by providing the folder, schema, title as hard corded.
if you can guide me how to add field value also in component, that would be great. (For example assume that i have a field "Text" in my schema which am linking to this component, and i want to add "This is the Text" in this field of my component using the same program.
can you please help me out on this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DctmToSDLMigration.SDLCoreServiceReference;
namespace DctmToSDLMigration
{
class Program
{
static DctmToSDLMigration.SDLCoreServiceReference.SessionAwareCoreService2010Client client = new SessionAwareCoreService2010Client();
static ReadOptions readoptions = new ReadOptions();
static void CreateComponent()
{
try
{
string TargetFolderTcmId = "tcm:148-1263-2";
string LinkSchemaTcmId = "tcm:148-11460-8";
ComponentData CurrentMigrationComponent = client.GetDefaultData(ItemType.Component, TargetFolderTcmId) as ComponentData;
LinkToSchemaData SchemaToUse = new LinkToSchemaData();
SchemaToUse.IdRef = LinkSchemaTcmId.ToString();
CurrentMigrationComponent.Schema = SchemaToUse ;
CurrentMigrationComponent.Title = "Test component";
client.Create(CurrentMigrationComponent, readoptions);
Console.WriteLine(CurrentMigrationComponent.Id);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
static void Main(string[] args)
{
CreateComponent();
}
}
}
You need to set the Content Property of the Component.
XmlDocument doc = new XmlDocument();
doc.LoadXml(string.Format(#"<Content xmlns='{0}'><Test>Hello</Test></Content>", SchemaToUse.NamespaceUri));
CurrentMigrationComponent.Content = doc.DocumentElement;

Can we fetch the file stored in the filestream through ssis script task?

I am trying to fetch the files from filestream using ssis script task and place the files in the destination folder , is their any standard approach to achieve this functionality .
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Xml;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
//Initialize XML Document to read the XML file
private XmlDocument xDoc = new XmlDocument();
public override void PreExecute()
{
base.PreExecute();
//Provide the path to read the XML file and load the xml document
xDoc.Load(#"C:\XML Sample\Input.xml");
}
public override void CreateNewOutputRows()
{
//Iterate through each node which has the value "Employee"
// "//Employee" is the xpath to fetch all occurences of Employee node in the XML
foreach (XmlNode xNode in xDoc.SelectNodes("//Employee"))
{
//Add new row to the output buffer for each employee node in the XML file
this.EmployeeBuffer.AddRow();
//Assign values to the columns.
//Read the 1st attribute of the node Employee
this.EmployeeBuffer.EmpID= xNode.Attributes[0].Value;
//Read the 1st Child node of the node Employee
this.EmployeeBuffer.Name= xNode.ChildNodes[0].InnerText;
//Read the 2nd Child node of the node Employee
this.EmployeeBuffer.Age= xNode.ChildNodes[1].InnerText;
}
}
public override void PostExecute()
{
base.PostExecute();
}
}

Resources