Uploading a document and sending within XForm - upload

I'm using EPiServer CMS 7.5 MVC application.
I can only see textboxes and buttons while creating a new form. I would like to have a link, which uploads a document, when clicked. Then this document should be able to view while looking to form data and also this should be attached along with the mail.
Any help?

There is no file upload control in XForm editor. One option - modify how XForm is rendered. XForm in EPiServer uses display templates to render. One way how to add file upload is to create your own XForm display template and add file upload. Display template will be used for all XForms in your application.
To create display template, create XForm.cshtml under /Views/Shared/DisplayTemplates/ in Visual Studio. Here is sample of source code of XForm.cshtml:
#using EPiServer.HtmlParsing
#using EPiServer.Web.Mvc.Html
#model EPiServer.XForms.XForm
#if (ViewData["XFormActionResult"] is EPiServer.Web.Mvc.XForms.XFormSuccessActionResult)
{
<strong>Form posted.</strong>
}
else
{
using (Html.BeginXForm(Model, new { #class = "form xform" }))
{
if (Model != null)
{
foreach (HtmlFragment fragment in (IEnumerable<HtmlFragment>)ViewData["XFormFragments"] ?? Model.CreateHtmlFragments())
{
// here can override particular fragment
// for example, check if TextBox Css class is "file-upload"
// then replace it with file upload
#Html.Fragment(fragment)
}
}
}
}
After that you have to handle posting the form yourself. This article describes well how to do it: http://www.eyecatch.no/blog/2013/01/using-xforms-and-mvc-in-an-episerver-7-block/
Then on OnActionExecuting in BasePageController you can handle file uploading. You can store it in the blob (in EPi 7 VPP) and store reference (GUID) in the XForm.

Related

Blazor Text Editor not able to bind value on form (create/edit)

I am using Blazor Text Editor from source below.
Source - https://github.com/Blazored/TextEditor
I successfully integrated it with my create and edit form, however not able to bind-Value to it. Because of this my Data Annotation Validation is failing.
Internally blazor is using Quill Editor, I am not looking for javascript option.
Sample Code of editor
<BlazoredTextEditor #ref="#QuillNative" Placeholder="Enter non HTML format like centering...">
<ToolbarContent>Some editor stuff here</ToolbarContent>
<BlazoredTextEditor
Could anyone please help me. How to bind-Value or correct approach without javascript.
Vencovsky - thanks of you prompt response, I was already aware of these methods however was curious to know if anybody had tried different option.
Below is what I did..
FORM -- This is common form for create & edit. OnValidSubmit will call respective Create/Edit method.
<EditForm Model="Entity" class="contact-form" OnValidSubmit="OnValidSubmit">
//My form fields here
//Commented the validation from that particular field
#*<ValidationMessage For="#(() =>Entity.field)" />*#
<div class="col-sm-1">
<button type="submit" #onclick="***getEditorData***" class="btn"
style="border:2px solid #555555;"><span>Save</span></button>
</div>
</EditForm>
METHOD -- getEditorData() gets fired before OnValidSubmit()
public async void getEditorData()
{
Enity.field = await this.QuillNative.GetHTML();
}
So in my final Entity on OnValidSubmit() I receive all fields along with editor data..
Hope this help if anyone is trying to do so..
Apparently you can't bind a value to it, but you should use the provided methods
Methods
GetText - Gets the content of the editor as Text.
GetHTML - Gets the content of the editor as HTML.
GetContent - Gets the content of the editor in the native Quill JSON Delta format.
LoadContent (json) - Allows the content of the editor to be programmatically set.
LoadHTMLContent (string) - Allows the content of the editor to be programmatically set.
InsertImage (string) - Inserts an image at the current point in the editor.
To use these methods you need a reference of it
#* Getting the BlazoredTextEditor reference*#
<BlazoredTextEditor #ref="#BlazoredTextEditorRef">
#* rest of the code*#
</BlazoredTextEditor>
And in some code in your class you can do
void LoadData(){
//var html = BlazoredTextEditor.LoadHTML(SomeDataToLoad)
BlazoredTextEditor.LoadText(SomeDataToLoad)
}
void ValidateData(){
//var html = BlazoredTextEditor.GetHTML()
var text = BlazoredTextEditor.GetText()
// do something to validate text
}
You can call these methods and use the referece in other methods, this is just an example on how to do it.
here is how I did this:
1- to bind the value on load:
<BlazoredTextEditor #ref="#QuillHtml">
<EditorContent>
#((MarkupString)infoBlock.Description)
</EditorContent>
</BlazoredTextEditor>
to get value on submit
<EditForm Model="infoBlock" OnValidSubmit="LocalOnValidSubmit">
...
#code {
....
[Parameter] public EventCallback OnValidSubmit { get; set; }
BlazoredTextEditor QuillHtml = new BlazoredTextEditor();
private async Task LocalOnValidSubmit()
{
infoBlock.Description = await this.QuillHtml.GetHTML();
await OnValidSubmit.InvokeAsync(this);//to call event handler passed by parent after the HTML prepared for main bound class
}
}

Umbaco Archtype rendering images (MediaPicker2)

I'm building a image slider using Archtype in Umbraco.
I was using umbraco 7.5.9 and Umbraco.MediaPicker when I started this but in the mean time I started a new project with the newest version Umbraco (7.6.2) which uses Umbraco.MediaPicker2
It was no problem rendering images with the old MediaPicker but with the MediaPicker2 it seems impossible.
Here is my setup.
The Archtype:
Here is the partial view that rendered the old MediaPicker
<div class="fullWidthSlider">
#foreach (var image in #CurrentPage.SliderImages)
{
<div>Id: #image.GetValue("image")</div>#*Line added for debug*#
var media = #Umbraco.Media(image.GetValue("image"));
<img src="#media.Url" />
}
</div>
This used to work for the old Media picker and the #image.GetValue returned int id. But with the new MediaPicker2 it returns Umbraco.Core.Udi[]
If I foreach through the properties of the archtype with the code below I get this result (see below code)
#foreach (var fieldset in Model.Content.GetPropertyValue<ArchetypeModel>("sliderImages"))
{
foreach(var prop in fieldset.Properties){
<p>#prop.Alias - #prop.Value</p>
}
}
href -
altText - alt test
image - umb://media/c33bfe07a82b4df18a79db154139cb91
href -
altText - Fjall
image - umb://media/40d5778d34bb4035b5146c901de75212
Can anyone tell me how I can render image from this data.
Thanks
I just went on a roller-coaster figuring this out!
You can get an IPublishedContent from your image string using this code:
// Your string which is retrieved from Archetype.
var imageString = "umb://media/c33bfe07a82b4df18a79db154139cb91";
// Get the guid from this string.
var imageGuidUdi = GuidUdi.Parse(imageString);
// Get the ID of the node!
var imageNodeId = ApplicationContext.Current.Services.EntityService.GetIdForKey(guidUdi.Guid, (UmbracoObjectTypes)Enum.Parse(typeof(UmbracoObjectTypes), guidUdi.EntityType, true));
// Finally, get the node.
var imageNode = Umbraco.TypedMedia(imageNodeId.Result);
Check out this thread on Our Umbraco which covers this issue.
I used this comment to figure out how to get the ID from the image's guid.
It looks like Umbraco HQ is pushing for people to use the new ModelsBuilder with typed models. I'm not sure if Archetype is supported by the ModelsBuilder which is why there's so much trouble.
I personally use Nested Content on all of my projects as it performs the same functionality but (IMO) is better supported by Umbraco because it uses Document Types to store repeatable content schema. Because of this, it can then easily be mapped to IPublishedContent and therefore is supported by the ModelsBuilder!

Asp .net core how to display RTF document file in page view cshtml

Please I need some help.
I want to build an online exam web application, so the question files as .rtf stored in database, then when the exam held, us as participant can see the questions by the button list in page.
How I can show/display any .RTF file document (from my database) to page view (.cshtml) ?
public class Exam_Question
{
....
public byte[] Question_File { get; set; }
}
I have stored the file in database.
Then in controller I call the model.
public async Task<IActionResult> Details(int? id)
{
var exam_Question = await _context.Question.SingleOrDefaultAsync(m => m.ID == id);
return View(exam_Question);
}
Then in page view I did try this.
<iframe src="data:#Model.Question_File; base64, #Convert.ToBase64String(Model.Question_File)"></iframe>
the result like this image : IFrame tag with base64 file
I want to display at least at same bold, size, paragraph, equation, etc format like in Word App.
I think one option will be to convert the RTF into HTML at server side and then rendering.
You could either use a paid library as below
SautinSoft
Or build your own RTF to HTML converter. Here is a link to CodeProject which provides pretty detailed breakdown
CodeProject
Sorry I cant think of a simpler solution at the moment
As a variant: Load RTF file and then to open in HTML.
string inpFile = #"..\..\..\..\example.rtf";
string outfile = Path.GetFullPath("Result.html");
RtfToHtml r = new RtfToHtml();
r.Convert(inpFile, outfile, new HtmlFixedSaveOptions() {Title = "Show the RTF." });

Render view from DB in MVC 6

We are working on ASP.NET MVC 6 project and it's necessary to render Razor views from other than file system source (Azure Blob storage in particular but it's not important).
Earlier (in MVC 5) it was possible to create and register custom VirtualPathProvider which can take view content from DB or resource DLLs (for example).
It seems that approach has been changed in MVC 6. Does anybody know where to look for?
UPD:
Here is an example of code I'm looking for:
public IActionResult Index()
{
ViewBag.Test = "Hello world!!!";
string htmlContent = "<html><head><title>Test page</title><body>#ViewBag.Test</body></html>";
return GetViewFromString(htmlContent);
}
The question is: how to implement that GetViewFromString function?
You need to configure a ViewLocationExpander:
services.SetupOptions<RazorViewEngineOptions>(options =>
{
var expander = new LanguageViewLocationExpander(
context => context.HttpContext.Request.Query["language"]);
options.ViewLocationExpanders.Insert(0, expander);
});
and here is the implementation for the LanguageViewLocationExpander :
https://github.com/aspnet/Mvc/blob/ad8ab4b8fdb27494f5dece6f1186acea03f9dd52/test/WebSites/RazorWebSite/Services/LanguageViewLocationExpander.cs
Basing your AzureBlobLocationExpander on that one should put you in the right track.
Just posted a sample of store .cshtml in Azure Blob Storage to GitHub.
See also my answer to another question on this
Basically you need to create an implementation of IFileProvider. This can then be registered in Startup.cs by configuring RazorViewEngineOptions
services.Configure<RazorViewEngineOptions>(options =>
{
options.FileProvider = new AzureFileProvider(Configuration);
});

Icons for each file type

In my MVC application, user can upload various type of files (pdf, jpg, txt etc) and I want to show icon specific to each type, currently I am using one icon (pdf) for the purpose, I want, that based on the file type, associated icon should be displayed. Please guide me what kind of approach I can use for this purpose
<td>
#if (item.CalibratedBy != null){
<a href = #Url.Action("ViewCertificate", new { fileName = item.CalibrationCert }) >
<img src = "#Url.Content("~/Content/Icons/pdf.jpg")" alt = "attachment" /> </a>
}
</td>
Expose the extension type needed as a property on item (presumably being passed in through the Model)
Create an HtmlHelper extension method that will take in item.FileType and return the path to the appropriate icon file to be used. Call this in your <img> tag.

Resources