I don’t want to make this post TL;DR, so I will try to keep it simple. I am trying to grab INCLUDETEXT fields from a document, replace the URL, and re-create/generate the field.
private void ReplaceFieldCode(Field field, string newFieldCode)
{
Document doc = (Document)field.Start.Document;
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToField(field, true);
RemoveField(field);
builder.InsertField(newFieldCode);
}
private void RemoveField(Field field)
{
Node currentNode = field.Start;
Node fieldEnd = field.End;
while (currentNode != null && currentNode != fieldEnd)
{
Node nextNode = currentNode.NextPreOrder(currentNode.Document);
currentNode.Remove();
currentNode = nextNode;
}
fieldEnd.Remove();
}
For my new field code, I am using a UNC pathname, and excel expects this to have two backslashes, but when I replace the backslashes, I get an error.
public async Task<string> DownloadFileToTempAsync(string url)
{
var stream = await DownloadFileAsync(url);
var fileExtension = Path.GetExtension(new Uri(url).AbsolutePath);
string tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + fileExtension);
using (var fileStream = File.Create(tempFilePath))
{
await stream.CopyToAsync(fileStream);
}
tempFilePath = tempFilePath.Replace("\\", "\\\\");
return tempFilePath;
}
This error occurs at builder.InsertField(newFieldCode);
and only occurs when I include the .Replace(). I’ve checked the difference between the two strings, and the only difference is that the second one has four backslashes instead of 2. I’m at a loss as to why its throwing this error.
@amattice If possible could you please also attach your input document and provide field code that causes the mentioned exception?
Also, why do you use a custom method for removing a field instead a built in Field.Remove() method?
In addition, if you goal is to update INCLUDETEXT
field source path, you can simply set FieldIncludeText.SourceFullName property.
1 Like
@alexey.noskov You are right…for some reason I was under the assumption I needed to replace the field entirely. Simplifying that seems to have also fixed my problem with backslash characters. Not sure if you could help me with this as well, but I am calling document.UpdateFields(), but I download the file and it still is not generated content.
public async Task ReplaceIncludeTextFieldsWithNewContent(Document document, ManifestModel manifest)
{
foreach (Field field in document.Range.Fields)
{
if (field.Type == FieldType.FieldIncludeText)
{
FieldIncludeText includeTextField = (FieldIncludeText)field;
string fieldCode = field.GetFieldCode();
var placeholderNameMatch = Regex.Match(fieldCode, "\"([^\"\\:]+)\\:.*?\"");
if (placeholderNameMatch.Success)
{
string placeholderName = placeholderNameMatch.Groups[1].Value;
var placeholder = manifest.Placeholders.FirstOrDefault(p => p.Placeholder == placeholderName);
if (placeholder != null && !string.IsNullOrWhiteSpace(placeholder.ContentUrl))
{
string tempFilePath = await _fileManagementService.DownloadFileToTempAsync(placeholder.ContentUrl);
includeTextField.SourceFullName = tempFilePath;
}
}
}
}
document.UpdateFields();
}
@amattice Please make sure the files specified in the INCLUDETEXT
fields are accessible. I have tested the scenario on my side using a simple document with one INCLUDETEXT
field and the following code:
Document doc = new Document(@"C:\Temp\in.docx");
// Get the first INCLUDETEXT field.
FieldIncludeText includeText = doc.Range.Fields.Where(f => f.Type == FieldType.FieldIncludeText)
.Cast<FieldIncludeText>().First();
// Update INCLUDETEXT field source.
includeText.SourceFullName = @"C:\Temp\src2.txt";
doc.UpdateFields();
doc.Save(@"C:\Temp\out.docx");
The field is updated properly.
1 Like
@alexey.noskov It appears that the links were correct but my word was set to automatically show the INCLUDETEXT on startup instead of the rendered content. I will have to look to see if there is a way to lock the fields in the rendered state, so users cannot view the field information.
@amattice Usually, MS Word automatically updates fields, which are marked as “dirty”. Please make sure Field.IsDirty property is set to false
after updating the field.