Dotliquid Template Render outputs filepath - c#

I am currently trying to work with DotLiquid in C# and I've observed a behavior that I don't quite understand. Since I am not very familiar with C#, I cannot say for sure if my issue is with C# itself, or DotLiquid, so please bear with me. =)
I have a very basic index.liquid that I am trying to pass a Table-object to.
For the sake of getting started, I've overridden toString() to simply create a representation, for now, I'll later want to work with the actual object. When trying to work with the template, this is what I do:
public static void createHTML(DataTable table)
{
string templatePath = #"C:\Path\To\index.liquid";
var template = Template.Parse(templatePath);
template.Render(Hash.FromAnonymousObject(new
{
table = DataMapper.createTable(table).toString()
});
using (StreamWrite file = new StreamWriter(#"C:\Some\Path\test.html"))
{
file.write(template.Render());
}
}
Now, when I open this newly created test.html, all it contains is C:\Path\To\index.liquid, meaning I am somehow not loading my template correctly. Looking at Try to use DotLiquid with c#
I would have thought that I am loading the template correctly and using File.ReadAllText(templatePath)); showed me that templatePath is pointing to the correct file.
This shows me that I'm not understanding something very basic about Template.Parse() or Template.Render() where the source code doesn't provide me with the insight I'm missing, so hopefully, you can help me out.

Hopefully saving others from getting tripped up on this. The real reason why the output is the filepath is because Template.Parse(string source) expects the actual template contents, not a file path.
In order to accomplish what you are attempting, you need to use it this way:
Template template = Template.Parse(File.ReadAllText(templatePath));

It is hard to tell without the content of index.liquid, but there is already one thing to fix: you are calling Render two times, and the second without your object.
Try this:
public static void createHTML(DataTable table)
{
string templatePath = #"C:\Path\To\index.liquid";
var template = Template.Parse(templatePath);
using (StreamWrite file = new StreamWriter(#"C:\Some\Path\test.html"))
{
file.write(template.Render(Hash.FromAnonymousObject(new
{
table = DataMapper.createTable(table).toString()
})));
}
}
If this doesn't work, please update your question to add the content of index.liquid.

Related

How Force browser to reload cached static file with versioning?

After deploying a new version of a website the browser loads everything from its cache from the old webpage until a hard, force refresh is done.
In ASP.NET MVC if the file becomes in Bundle, it handled by Optimization framework. a version added to your file link, and if a change occurs in your bundle's file a new token generate. follow below code :
for example, js file name is: datatables
when you put it in a bundle with the same name, you will see the
datatables?v=anY9_bo7KitrGnXQr8ITP3ylmhQe9NDzSjgLpLQWQFE1
as a file name.
change datatables and watch again the name of the file in the browser, surely it will change:
datatables?v=r8yhQBxKyDgrOGyqr1ndtdG92Ije09nqTY7yogrOSTk1
But there's two questions:
What we can do if our file wasn't in Bundle?
Is a way to force the browser to refresh cache?
we have one solution with some different way for implementation. we use above solution for it.
datatables?v=1
we can handle the version of the file, it's mean that every time that we change our file, change the version of it too. but it's not a suitable way.
another way used Guide, it wasn't suitable too, because each time it fetches the file and doesn't use from the browser cache.
datatables?v=Guid.NewGuid()
The last way that is the best Way is :
when file change occur , change version too. check follow code :
<script src="~/scripts/main.js?v=#File.GetLastWriteTime(Server.MapPath("/scripts/main.js")).ToString("yyyyMMddHHmmss")"></script>
by this way, when you change the file, LastWriteTime change too, so the version of the file will change and in the next when you open the browser, it detects a new file and fetch it.
Assuming you cannot use bundling for some reason, the solution suggested by the original poster is good enough, however it's better to put the logic inside a helper method.
It makes the code testable, it helps to change the logic without changing .cshtml , and also helps to not repeat the filename twice. Then you can have have a much cleaner code:
<script src="#Url.ContentWithVersion("~/scripts/main.js")"></script>
To do so, you can add ContentWithVersion extension method to the existing UrlHelper:
using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
public static class UrlHelperExtensions
{
public static string ContentWithVersion(this UrlHelper urlHelper, string path)
{
if (urlHelper == null)
throw new ArgumentNullException(nameof(urlHelper));
var result = urlHelper.Content(path);
var file = HttpContext.Current.Server.MapPath(path);
if (File.Exists(file))
result += $"?v={File.GetLastWriteTime(file).ToString("yyyyMMddHHmmss")}";
return result;
}
}

Dynamic Update using the visual designer: is it possible, or better to convert flows to code?

Related to my earlier question about updating long-running flows with multiple child flows and custom activities, I'm working on implementing a plan as well as code for modifying workflows after they've been released to production.
Besides the various issues outlined in the other question, I'm trying to debug the visual designer appearing jumbled after prepping it for dynamic update. After running diffs on the .xaml, it appears to be an issue with the WorkflowViewState getting confused.
According to previous posts, it seems that abandoning the visual designer is one sure-fire way of solving this problem. However, I've found code that seems to nearly get me there. Here is how I'm saving the MainProcessFlow.xaml back to the file, after calling the DynamicUpdateServices.PrepareForUpdate method:
private static void SaveBuilderToFile(ActivityBuilder builder, string filePath)
{
// Make sure the activity builder has the right information about the c# expressions (even though its visual basic)
VisualBasic.SetSettings(builder, VisualBasic.GetSettings(builder));
// Set c# as the language
System.Activities.Presentation.Expressions.ExpressionActivityEditor.SetExpressionActivityEditor(builder, "C#");
// This is what I was hoping would correctly set the Viewstate
WorkflowViewState.SetViewStateManager(
builder.Implementation, WorkflowViewState.GetViewStateManager(builder.Implementation));
string fullPath = Path.GetFullPath(filePath);
using (FileStream file = File.Create(fullPath))
{
using (XmlWriter xmlWriter = XmlWriter.Create(file, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }))
{
using (XamlWriter xamlWriter = ActivityXamlServices.CreateBuilderWriter( new XamlXmlWriter(xmlWriter, new XamlSchemaContext())))
{
XamlServices.Save(xamlWriter, builder);
}
}
}
}
After calling this method and opening the .xaml up in the visual designer, the activities are out of order. The flows are still "correct", in that the arrows are pointing in the right direction, but the layout is jumbled. After making my changes, creating the update map, and saving the .xaml back without the dynamicupdate information, the order is still incorrect. There is not very much documentation (that I can find) on setting the Viewstate in the xaml. Am I missing something?
Alternatively, is abandoning the visual designer a better option? We have nearly a years worth of Workflows, so it would be an immense undertaking, but getting DynamicUpdate working is a higher priority.
I just fixed such problem and I did it by taking WorkflowViewState.GetViewStateManager(builder.Implementation) before DynamicUpdateServices.PrepareForUpdate(builder). I don't know what is the problem, but after I PrepareForUpdate and the result from GetViewStateManager is null.
After I do all stuff, I pass the ViewStateManager to SaveBuilderToFile() and use it there.

Dynamically compiled project losing resources

I need to compile source code of big project dynamically and output type can be Windows Application or Class Library.
Code is nicely executed and its possible to make .dll or .exe files, but problem is that, when I'm trying to make .exe file - it's losing resources like project icon. Result file doesn't include assembly information to.
Any way to solve this? (Expected result should be the same, that manual Build function on project file in Visual Studio 2015).
Thank you!
var workspace = MSBuildWorkspace.Create();
//Locating project file that is WindowsApplication
var project = workspace.OpenProjectAsync(#"C:\RoslynTestProjectExe\RoslynTestProjectExe.csproj").Result;
var metadataReferences = project.MetadataReferences;
// removing all references
foreach (var reference in metadataReferences)
{
project = project.RemoveMetadataReference(reference);
}
//getting new path of dlls location and adding them to project
var param = CreateParamString(); //my own function that returns list of references
foreach (var par in param)
{
project = project.AddMetadataReference(MetadataReference.CreateFromFile(par));
}
//compiling
var projectCompilation = project.GetCompilationAsync().Result;
using (var stream = new MemoryStream())
{
var result = projectCompilation.Emit(stream);
if (result.Success)
{
/// Getting result
//writing exe file
using (var file = File.Create(Path.Combine(_buildPath, fileName)))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(file);
}
}
}
We never really designed the workspace API to include all the information you need to emit like this; in particular when you're calling Emit there's an EmitOptions you can pass that includes, amongst other things, resource information. But we don't expose that information since this scenario wasn't hugely considered. We've done some of the work in the past to enable this but ultimately never merged it. You might wish to consider filing a bug so we officially have the request somewhere.
So what can you do? I think there's a few options. You might consider not using Roslyn at all but rather modifying the project file and building that with the MSBuild APIs. Unfortunately I don't know what you're ultimately trying to achieve here (it would help if you mentioned it), but there's a lot more than just the compiler invocation that is involved in building a project. Changing references potentially changes other things too.
It'd also be possible, of course, to update MSBuildWorkspace yourself to pass this through. If you were to modify the Roslyn code, you'll see we implement a series of interfaces named "ICscHostObject#" (where # is a number) and we get passed the information from MSBuild to that. It looks like we already stash that in the command line arguments, so you might be able to pass that to our command line parser and get the data back you need that way.

How to remove a certain print to file feature of Devexpress document Viewer

hi im just wondering when i tried to print the report on devexpress document viewer i found a weird feature that i donw really need in terms of functionality and i want to remove it is there a way to remove it??.. this is the feature that i want to remove kindly see image for reference
Is there a way to remove it? i spend hours looking for solution for this but i cant find it i just thought that you guys could possibly help me thank in advance
You can replace the DefaultPrintDialogRunner, returned by the PrintDialogRunner.Instance property, with a customized version of the SystemPrintDialogRunner or the DefaultPrintDialogRunner class.
Here is the way to replace the default PrintDialogRunner:
using DevExpress.XtraEditors.Preview;
// ...
static void Main(string[] args) {
PrintDialogRunner.Instance = new SystemPrintDialogRunner(); // !!!
// ...
}
The code above will result that the PrintTool.PrintDialog method will invoke the standard system Print dialog:
Then you should create your own version of PrintDialogRunner that invokes the PrintDialogRunner.Run method with the the specific flags and use this class in the approach mentioned above:
class CustomPrintDialogRunner : DefaultPrintDialogRunner {
public override DialogResult Run(PrintDocument document, UserLookAndFeel lookAndFeel,
IWin32Window owner, PrintDialogAllowFlags flags) {
// Disable the print-to-file option.
flags &= ~PrintDialogAllowFlags.AllowPrintToFile;
return base.Run(document, lookAndFeel, owner, flags);
}
}
//...
PrintDialogRunner.Instance = new CustomPrintDialogRunner ();

Silverlight C# - ComponentOne Spellchecker not loading dictionary

This may be a long shot, but I'm using ComponentOne's Spellchecker control for Silverlight. I made a test project, added a plain textbox and a button to it, added the references to the C1.Silverlight and C1.Silverlight.SpellChecker bits, and added the dictionary file to my project.
In the code, I called up the spellchecker on button1's click event and it worked SPLENDIDLY. The spellchecker dialog shows up, and works exactly as it should.
Since that test was successful, I then tried to implement this into my existing project. I've had no success for absolutely NO reason that I can determine, since I used the EXACT SAME code.
Here's the code I use to call the component:
using C1.Silverlight;
using C1.Silverlight.SpellChecker;
using C1.Silverlight.Resources;
public partial class MainPage : UserControl
{
C1SpellChecker spellChecker = new C1SpellChecker();
public MainPage()
{
InitializeComponent();
spellChecker.MainDictionary.LoadAsync("C1Spell_en-US.dct");
}
private void btnSpelling_Click(object sender, RoutedEventArgs e)
{
var dlg = new C1SpellDialog();
spellChecker.CheckControlAsync(txtArticle, false, dlg);
}
The references to C1.Silverlight and C1.Silverlight.Spellchecker are added to this project as well, and the dictionary as been added in the same fashion as well. The issue seems to be that for whatever reason the dictionary is not loading, because the spellChecker.Enabled method returns whether or not the main dictionary has been loaded. If I call MessageBox.Show("SpellChecker Enabled = " + spellChecker.Enabled.ToString()); it shows false, even though the call to load the dictionary is there (as you can see).
What would cause the dictionary to not load? Have I added it to my project incorrectly somehow?
EDIT: I suspect that I have added the dictionary to the project incorrectly, because the ComponentOne reference states:
If C1SpellChecker cannot find the
spelling dictionary, it will not throw
any exceptions. The Enabled property
will be set to false and the component
will not be able to spell-check any
text.
I just don't know what's wrong though because it was added in the same way that it was in the test project (Right clicked on the project.web->Add->Existing Item)
As always, thank you!
-Sootah
You could add the dictionary to the Silverlight app as an embedded resource and then load it using this code:
public MainPage()
{
InitializeComponent();
// load C1SpellChecker dictionary from embedded resource
var asm = this.GetType().Assembly;
foreach (var res in asm.GetManifestResourceNames())
{
if (res.EndsWith(".dct"))
{
using (var s = asm.GetManifestResourceStream(res))
{
sc.MainDictionary.Load(s);
break;
}
}
}
}
I think this post is duplicated in our forum as well, but will answer first here. Please try this:
1) Try to access the .dct file using your browser. If you cannot see it, it's probably because your web server is not serving that type of files. You need ton configure the web server to allow it.
2) verify the URL you are using is correct.http://helpcentral.componentone.com/CS/silverlight_161/f/78/p/86955/241328.aspx#241328
3) Check you are setting everything correctly: http://helpcentral.componentone.com/CS/silverlight_161/f/78/p/81924/227790.aspx#227790
Hope this helps!

Categories