I want to archive a pdf version of a DESADV, therefore I create a Html page via Biztalk Custom XSLT Mapping from the original XML file and render it via Pechkin.Synchronized to a pdf (wrapper for wkhtmltopdf).
This works like a charm in my Solution, but once I try to deploy the solution to the QA System biztalk keeps nagging that it can not find the Pechkin Library.
The Libs are deployed via "gacutil -I", I even build it from source and signed it with our Biztalk signing key and changed the build mode from x86 to "any CPU".
I added all the needed dlls to the Helper Class and deployed them also manually but BizTalk is unable to access the lib. Please help me, I am trying for days without making any progress and it makes me mad.
I even struggle to debug why it can not load the dll.
I am not so fluent in BizTalk and always thought that DLLs in the GAC are accessible to BizTalk...
I also build a console application, that directly references to the DLL in GAC_MSIL and the application renders the html with the exact code, I wrote in the BizTalk Solutions helper class.
even this can not be considered a real answer but it solved the problem somehow.
As already someone mentioned it, the DLL had dependencies onto other libs. This in combination that I was unable to deploy the DLL to the gac and no deeper understanding of the topic I simply chose another lib as this already took to much time. meh.
I choose the shareware https://selectpdf.com/community-edition/, they have a nuget package that simply worked. (i like). The overall render speed is not as good, but in the end it is more important to stay BizTalk compatible with your project I guess.
If someone stumbles upon this:
Create XSL Mapping for your Message XML and map it to some fancy
HTML layout (css supported)
Xtract XML from BizTalk Message in Orchestration
Render PDF with a Helper Solution
My code of the helper class:
You need to add the "Microsoft.XLANGs.BaseTypes" reference from References->Add reference->Assemblies->Extensions for it to work.
using System;
using Microsoft.XLANGs.BaseTypes;
using System.IO;
namespace BIS.CLC.DESADV.Helper
{
public class HtmlHelper
{
public string xTractStringFromMessage(XLANGMessage message)
{
string retVal = string.Empty;
try
{
using (var reader = new StreamReader(message[0].RetrieveAs(typeof(Stream)) as Stream))
{
retVal = reader.ReadToEnd();
}
}
catch (Exception ex)
{
Exception logex = new Exception("BIS.CLC.DESADV.Helper.HtmlHelper.xtractStringFromMsg: string extraction failed" + ex.Message.ToString() + ex.InnerException.ToString());
BIS.Common.Helper.StaticClass.writeEventLog_BizTalk(logex.Message.ToString(), "BisLog");
throw ex;
}
finally
{
message.Dispose();
}
return retVal;
}
public void renderPDFfromHTML(string html, string targetPath)
{
try
{
//do things
SelectPdf.HtmlToPdf converter = new SelectPdf.HtmlToPdf();
SelectPdf.PdfDocument doc = converter.ConvertHtmlString(html);
doc.Save(new Uri(targetPath).LocalPath.Replace(".XML", ".PDF"));
doc.Close();
}
catch (Exception ex)
{
Exception logex = new Exception("BIS.CLC.DESADV.Helper.HtmlHelper.renderPDFfromHTML: render pdf failed " + ex.Message.ToString() + ex.InnerException.ToString());
BIS.Common.Helper.StaticClass.writeEventLog_BizTalk(logex.Message.ToString(), "BisLog");
throw ex;
}
}
}
}
Related
I have developed a WCF in ASP.NET 4.5 with a couple of simple methods. One such method has a return type of bool (written in c#). When I add this service to my ASP.NET 4.5 web application as a Service Reference, it works as expected in the code behind. It also works the same way in a .NET 4.5 C# Console application. Below is the code in the Implementation file for this method:
public bool AddADUser(string a, string b)
{
bool done = false;
return done;
}
When I call it from my programs, it looks like this:
static void Main(string[] args)
{
var proxy = new ServiceReference1.ADServiceClient();
proxy.Open();
try
{
Console.WriteLine(proxy.HelloWorld());
bool success = proxy.AddADUser("testA", "testB");
Console.WriteLine(success.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.InnerException);
}
finally
{
proxy.Close();
}
}
This is how it works in my ASP.NET 4.5 / C# app, and my C# .NET 4.5 Console App.
When I add this as a "Web Reference" to an existing ASP.NET 2.0 / VB.NET app, it does something different. The command to call the AddADUser() function is all of a sudden requiring 4 parameters:
AddADUser(a As String, b As String, ByRef AddADUserResult As Boolean, ByRef AddADUserResultSpecified As Boolean)
Why are these parameters being added -- is this something with VB.NET not allowing this to actually return a boolean, or a web reference not being able to return a boolean, or a problem with this being ASP.NET 2.0 ?
Or do I need to make a custom DataContract? I have that part left out of my Interface, just relying on defaults. Do I need to specify XmlSerializer somewhere also to be able to use this? It appears to actually do what it is supposed to, and I just can't figure out why there are two booleans and which one is the one I want.
This page gives a long explanation about it and a weird workaround that I didn't feel like doing:
http://www.codeproject.com/Articles/323097/WCF-ASMX-Interoperability-Removing-the-Annoying-xx
What I wound up doing was adding
[OperationContract, XmlSerializerFormat(Style = OperationFormatStyle.Rpc)]
to my methods and I also added
[ServiceContract,XmlSerializerFormat]
to my interface attribute and now they act like I would expect.
Reference: http://www.wenda.io/questions/1191041/result-and-resultspecified-parameters-in-wcf-service.html
I'm hunting for a bug, and it would be really helpful if I could dump the contents of the objects my Locals Window to a file so that I could compare it in Notepad++ with another object record that works correctly. The problem is this: we are not sure if there is a bug in code or a discrepancy in the record.
Is there some way to save a object/variable to disk?
I found this extension, but sadly it is only for VS 2010, and I have 2012.
You could use the ObjectDumper extension. It's also available as a NuGet package.
I'm a bit late to the party but I created a Visual Studio extension called Object Exporter that does exactly what you're looking for. It will export any object in your debugging windows (currently only limited to the locals window) to JSON, XML or CSharp object initialization code.
Here's the extension: Visual Studio Marketplace > Object Explorer
And here's an accompanying blog post: Exporting Objects from the Visual Studio Debugger
The sources of the Export Locals extension made available for download by the author at
http://barad-dur.nl/net/export-locals/ so you should be able to convert it to VS2012 easily.
I work at OzCode. It's a debugging extension for Visual Studio and we've been working on a feature that exports instances as XML, json or C# code for a future version.
You can download the early access preview from Visual Studio's marketplace.
It's a commercial grade solution which enable exporting large amount of data - quickly.
I suggest you try it out - once you install OzCode using Export is just a matter of opening the DataTip window and choosing "Export".
Try opening Immediate Window and type object name. It'll print out the simple properties and their values. It does not handle properties that are objects well, though.
Alternatively, you could use JSON serializer to serialize it and print it out in debug console.
I did a little experimentation with Log4Net and ObjectDumper to dump objects.
Check out my blog post: Logging Complete Objects with Log4Net
Basically you create your own IObjectRenderer, configure it, and then you can simply log.Debug(yourObject)
public class Log4NetObjectLogger : IObjectRenderer
{
public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
{
var ex = obj as Exception;
//if its not an exception, dump it. If it's an exception, log extended details.
if (ex == null)
{
//by default log up to 10 levels deep.
ObjectDumper.Write(obj,10,writer);
}
else
{
while (ex != null)
{
RenderException(ex, writer);
ex = ex.InnerException;
}
}
}
private void RenderException(Exception ex, TextWriter writer)
{
writer.WriteLine(string.Format("Type: {0}", ex.GetType().FullName));
writer.WriteLine(string.Format("Message: {0}", ex.Message));
writer.WriteLine(string.Format("Source: {0}", ex.Source));
writer.WriteLine(string.Format("TargetSite: {0}", ex.TargetSite));
RenderExceptionData(ex, writer);
writer.WriteLine(string.Format("StackTrace: {0}", ex.StackTrace));
}
private void RenderExceptionData(Exception ex, TextWriter writer)
{
foreach (DictionaryEntry entry in ex.Data)
{
writer.WriteLine(string.Format("{0}: {1}", entry.Key, entry.Value));
}
}
}
using TDS = Tridion.ContentManager.Interop.TDS;
using Tridion.ContentManager.Interop.TDS;
using Tridion.ContentManager.Interop.TDSDefines;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Xml.Linq;
namespace ConsumerHealth.Web
{
class Common
{
public Common()
{
}
public TridionCollection<Publication> getAllPublicationList()
{
TDSE objTom = new TDSE();
try
{
TridionCollection<Publication> publications = new TridionCollection<Publication>(objTom.GetListPublications(ListColumnFilter.XMLListIDAndTitle));
return publications;
}
catch (Exception ex)
{
throw ex;
}
finally
{
Marshal.ReleaseComObject(objTom);
}
}
}
}
public TridionCollection<Publication> getAllPublicationList(), it shows an error TridionCollection could not found, what am I missing, which dll should I use,
except this all is working fine.
I think Tridion Collection is user defined class, it is not there in any Tridion dll.
That is not a class that is provided by the Content Manager.
A quick Google search shows that a "Tridion Generic .NET Collections" extension for 2009 provided this. My guess is that you'd have to rewrite it for 2011.
You need this assembly provided by your dear friends at SDLTridionWorld.com.
This was written for Tridion 2009 (as was already mentioned before) and as far as I know it might not work on Tridion 2011. Given that it is open source, feel free to change it and adapt it as needed, and report it back to SDL Tridion World so they can update it with a newer version.
I use code below to read AssemblyTitle attribute of .NET apps, unfortunately Assembly.GetEntryAssembly() always return Null in ASP.NET app. How to read AssemblyTitle in ASP.NET app?
public static string Title
{
get
{
var attributes = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
var titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title.Length > 0)
return titleAttribute.Title;
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().CodeBase);
}
}
You must have a type that you know is defined in the same assembly that contains the AssemblyTitle. Then you can do:
typeof(MyType).Assembly.GetCustomAttributes
Note that (for what I know) there isn't any other bulletproof method.
For example using HttpContext.Current doesn't work if you want to do it not during a web request (so you can do it on response of a user action, but not from a separate thread, or from a static initializer, or from global.asax)
Some similar readings (full of half successes):
GetEntryAssembly for web applications
Using the Web Application version number from an assembly (ASP.NET/C#)
I use the following in asp.net web app:
if (ApplicationDeployment.IsNetworkDeployed)
return ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
Edit: Sorry, thats just the version, not the title! I combined your version and mine:
System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
That gets the assembly title attribute just fine. The difference is in GetExecutingAssembly() versus your GetEntryAssembly().
I have created a wcf service called ServiceIRE. I add a service reference to my project by right clicking on th eproject in solution explorer and clicking add Service Reference. I am able to discover my created service and click ok after specifying the namespace ServiceReference1. All files seem to be generated properly.
I then go to the codebehind and try to add a using statment "using ServiceReference1;". This is unrecognized by the file even though the namespace apparently exists in the same project.
Any help would be greatly appreciated.
ServiceIRE.cs
namespace FakeIREServiceLibrary
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ServiceIRE : IServiceIRE
{
public string GetData()
{
Random rnd = new Random();
var randomNumber = rnd.Next(10);
Random rndID = new Random();
var randomNumberID = rnd.Next(10000);
Thread.Sleep(randomNumber*1000);
return string.Format("Thread # {0} returned in {1} nanoseconds", randomNumberID, rnd.Next());
}
}
IServiceIRE.cs
namespace FakeIREServiceLibrary
{
[ServiceContract]
public interface IServiceIRE
{
[OperationContract]
string GetData();
}
}
Page.aspx.cs
using ServiceReference1; //THIS IS NOT RECOGNIZED
Thank you in advance :)
What's the default namespace for your project?
I believe you have to do something like "using DefaultNamespaceForProject.ServiceReference1;"
You can find the default namespace by right clicking your project.. clicking Properties, and then going to the Application tab.
You can find the namespace of the service client generated by Visual Studio by looking at the Reference.cs file within the Service Reference after you show all files for that project. The default is [Project namespace].[Namespace specified].
It's possible that it did NOT generate the file because of an error. That may be the behavior you're seeing.
I would also encourage you to NOT use Add Service Reference, but to instead use a ChannelFactory or build a reusable service client.