<ejs-richtexteditor id="questionEditor" name="question">
<e-richtexteditor-insertimagesettings saveUrl="WHATTOUSEHERE" path="/.images/"></e-richtexteditor-insertimagesettings>
<e-richtexteditor-toolbarsettings items="@ViewData["ToolbarOptions"]"></e-richtexteditor-toolbarsettings>
<e-content-template>
</e-content-template>
</ejs-richtexteditor>
public async Task<IActionResult> OnPostUpload(List<IFormFile> UploadFiles)
{
...
}
public void ConfigureServices(IServiceCollection services) // Add below code
{
services.AddMvc().AddJsonOptions(x =>
{
x.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
services.AddAntiforgery(o => o.HeaderName = "xsrf-token");
} |
@model IndexModel
@Html.AntiForgeryToken()
<ejs-richtexteditor id="rte" toolbarClick="toolbarClick">
<e-richtexteditor-insertimagesettings saveUrl="/Index?handler=Save" path="../">
</e-richtexteditor-insertimagesettings>
<e-content-template>
<p>
Users can format their content using standard toolbar commands.
</p>
</e-content-template>
</ejs-richtexteditor>
<script>
function toolbarClick(e) { // Triggered when you click the toolbar
if (e.item.id == "rte_toolbar_Image") { // Checked if image toolbar is clicked
var element = document.getElementById('rte_upload') // Image uploader element
element.ej2_instances[0].uploading = function upload(args) { // Added updating event on image uploader
args.currentRequest.setRequestHeader('XSRF-TOKEN', document.getElementsByName('__RequestVerificationToken')[0].value);
}
}
}
</script> |
private IHostingEnvironment hostingEnv;
public IndexModel(IHostingEnvironment env)
{
this.hostingEnv = env;
}
[AcceptVerbs("Post")]
public IActionResult OnPostSave(IList<IFormFile> UploadFiles) // Triggered when uploading image
{
try
{
foreach (var file in UploadFiles)
{
if (UploadFiles != null)
{
var filename = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
filename = hostingEnv.WebRootPath + $@"\{filename}";
if (!System.IO.File.Exists(filename))
{
using (FileStream fs = System.IO.File.Create(filename))
{
file.CopyTo(fs);
fs.Flush();
}
}
else
{
Response.Clear();
Response.StatusCode = 204;
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File already exists.";
}
}
}
}
catch (Exception e)
{
Response.Clear();
Response.ContentType = "application/json; charset=utf-8";
Response.StatusCode = 204;
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "No Content";
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;
}
return Content("");
} |
Hello Felix,
Thank you for contacting us.
Query 1: “What's the recommended way to use a specific upload directory in Razor Pages projects, when using RTE? Can SaveURL also be used with Razor Pages when the handler method is in code behind?”Yes. You can achieve upload using the saveUrl property and handler from code behind of Razor pages. But you need to add the below configurations to achieve it.
- Add AntiForgery token in startup file or web.config file.
[Startup.cs]
public void ConfigureServices(IServiceCollection services) // Add below code{services.AddMvc().AddJsonOptions(x =>{x.SerializerSettings.ContractResolver = new DefaultContractResolver();});services.AddAntiforgery(o => o.HeaderName = "xsrf-token");}
- Setup AntiForgery token in uploading event of Rich Text Editor image uploader through object using toolbarClick event. We have added ValidateAntiForgeryToken attribute on the server-side method when Rich Text Editor image uploading event triggered.
[Index.cshtml]
@model IndexModel@Html.AntiForgeryToken()<ejs-richtexteditor id="rte" toolbarClick="toolbarClick"><e-richtexteditor-insertimagesettings saveUrl="/Index?handler=Save" path="../"></e-richtexteditor-insertimagesettings><e-content-template><p>Users can format their content using standard toolbar commands.</p></e-content-template></ejs-richtexteditor><script>function toolbarClick(e) { // Triggered when you click the toolbarif (e.item.id == "rte_toolbar_Image") { // Checked if image toolbar is clickedvar element = document.getElementById('rte_upload') // Image uploader elementelement.ej2_instances[0].uploading = function upload(args) { // Added updating event on image uploaderargs.currentRequest.setRequestHeader('XSRF-TOKEN', document.getElementsByName('__RequestVerificationToken')[0].value);}}}</script>[Index.cshtml.cs]
private IHostingEnvironment hostingEnv;public IndexModel(IHostingEnvironment env){this.hostingEnv = env;}[AcceptVerbs("Post")]public IActionResult OnPostSave(IList<IFormFile> UploadFiles) // Triggered when uploading image{try{foreach (var file in UploadFiles){if (UploadFiles != null){var filename = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');filename = hostingEnv.WebRootPath + $@"\{filename}";if (!System.IO.File.Exists(filename)){using (FileStream fs = System.IO.File.Create(filename)){file.CopyTo(fs);fs.Flush();}}else{Response.Clear();Response.StatusCode = 204;Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File already exists.";}}}}catch (Exception e){Response.Clear();Response.ContentType = "application/json; charset=utf-8";Response.StatusCode = 204;Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "No Content";Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;}return Content("");}
We have attached the example application for your reference, please find it in the following location:http://www.syncfusion.com/downloads/support/directtrac/general/ze/RTE_razor_page_image_url1164633411Query 2: “I've seen an example https://ej2.syncfusion.com/aspnetcore/documentation/rich-text-editor/image/?no-cache=1. But this one uses controllers which is more related to the MVC pattern.”Currently, we have used MVC pattern for server-side actions in ASP.NET Core UG documentation.Query 3: “Without providing any directly upload seems to work, at least I get an URL within the img src tag. But can't find the image after uploading, so I thought it might be better to handle this manually”If you want to upload image without insertimagesettings property, you can upload the image directly and render it in editor. Suppose if you are going to configure insertimagesettings property, you need to specify path property. The editor considers the path property to render the image in editor. The saveUrl represents the URL to an action result method to save the image, and the path represents the destination folder in which the image must be saved.Let us know if you need any further assistance on this.
Regards,Prince
@model IndexModel
<ejs-richtexteditor id="rte" toolbarClick="toolbarClick" value="@Model.RteValue">
<e-richtexteditor-insertimagesettings saveUrl="/Index?handler=Save" path="../"></e-richtexteditor-insertimagesettings>
</ejs-richtexteditor> |
public string RteValue { get; set; }
public void OnGet()
{
RteValue = "<p>This is <b>RTE</b> Content</p>";
} |
<form method="post">
<ejs-richtexteditor ejs-for="RteValue" id="rte" toolbarClick="toolbarClick" >
<e-richtexteditor-insertimagesettings saveUrl="/Index?handler=Save" path="../"></e-richtexteditor-insertimagesettings>
</ejs-richtexteditor>
<br />
<input type="submit" />
</form> |
public void OnPost(string RteValue)
{
var value = RteValue;
} |
<div class="row">
<div class="col-lg-12">
<form method="post" asp-page-handler="post">
<div class="form-group">
<label asp-for="LearnContent.Question" class="control-label" ></label>
<ejs-richtexteditor id="questEditor" name="quest" toolbarClick="toolbarClickQuestion">
<e-richtexteditor-insertimagesettings saveUrl="Edit?handler=Save" path="../uploadedImages/"></e-richtexteditor-insertimagesettings>
<e-richtexteditor-toolbarsettings items="@ViewData["ToolbarOptions"]"></e-richtexteditor-toolbarsettings>
<e-content-template>
@Model.LearnContent.Question
</e-content-template>
</ejs-richtexteditor>
<script>
function toolbarClickQuestion(e) {
if (e.item.id == "questEditor_toolbar_Image") {
var element = document.getElementById('questEditor_upload')
element.ej2_instances[0].uploading = function upload(args) {
args.currentRequest.setRequestHeader('XSRF-TOKEN', document.getElementsByName('__RequestVerificationToken')[0].value);
}
}
}
</script>
</div>
<div class="form-group">
<label asp-for="LearnContent.Answer" class="control-label" ></label>
<ejs-richtexteditor id="answerEditor" name="answer" toolbarClick="toolbarClickAnswer">
<e-richtexteditor-insertimagesettings saveUrl="Edit?handler=Save" path="../uploadedImages/"></e-richtexteditor-insertimagesettings>
<e-richtexteditor-toolbarsettings items="@ViewData["ToolbarOptions"]"></e-richtexteditor-toolbarsettings>
<e-content-template>
@Model.LearnContent.Answer
</e-content-template>
</ejs-richtexteditor>
<script>
function toolbarClickAnswer(e) {
if (e.item.id == "answerEditor_toolbar_Image") {
var element = document.getElementById('answerEditor_upload')
element.ej2_instances[0].uploading = function upload(args) {
args.currentRequest.setRequestHeader('XSRF-TOKEN', document.getElementsByName('__RequestVerificationToken')[0].value);
}
}
}
</script>
</div>
<input type="hidden" asp-for="@Model.LearnContent.Id" name="id"/>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default"/>
</div>
</form>
</div>
</div>
<form method="post">
<div class="form-group">
<ejs-richtexteditor ejs-for="RteValue" id="rte" toolbarClick="toolbarClick">
<e-richtexteditor-insertimagesettings saveUrl="/Index?handler=Save" path="../"></e-richtexteditor-insertimagesettings>
</ejs-richtexteditor>
</div>
<div class="form-group">
<ejs-richtexteditor ejs-for="RteValue1" id="rte1" toolbarClick="toolbarClick1">
<e-richtexteditor-insertimagesettings saveUrl="/Index?handler=Save" path="../"></e-richtexteditor-insertimagesettings>
</ejs-richtexteditor>
</div>
<br />
<input type="submit" />
</form>
<script>
function toolbarClick(e) {
if (e.item.id == "rte_toolbar_Image") {
this.imageModule.uploadObj.uploading = function upload(args) {
args.currentRequest.setRequestHeader('XSRF-TOKEN', document.getElementsByName('__RequestVerificationToken')[0].value);
}
}
}
function toolbarClick1(e) {
if (e.item.id == "rte1_toolbar_Image") {
this.imageModule.uploadObj.uploading = function upload(args) {
…..
}
}
}
</script> |
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.LearnContentList[0].Picture)
th>
<th>
@Html.DisplayNameFor(model => model.LearnContentList[0].Question)
th>
<th>
@Html.DisplayNameFor(model => model.LearnContentList[0].Answer)
th>
<th>th>
tr>
thead>
<tbody>
@for (int i = 0; i < Model.LearnContentList.Count; i++){
<tr>
<td>
@Html.DisplayFor(modelItem => modelItem.LearnContentList[i].Question)
td>
<td>
<ejs-richtexteditor id="@i" name="@i + editor" value="@Model.LearnContentList[i].Answer" >
<e-richtexteditor-insertimagesettings path="../uploadedImages/">e-richtexteditor-insertimagesettings>
<e-content-template>e-content-template>
ejs-richtexteditor>
td>
<td>
<a asp-page="./Edit" asp-route-id="@Model.LearnContentList[i].Id">Edita> |
<a asp-page="./Details" asp-route-id="@Model.LearnContentList[i].Id">Detailsa> |
<a asp-page="./Delete" asp-route-id="@Model.LearnContentList[i].Id">Deletea>
td>
tr>
}
}
tbody>
table>
|
|
<ejs-richtexteditor id="@i" name="@i + editor" value="@Model.LearnContentList[i].Answer" >
<ejs-richtexteditor id="test+@i" value="@Model.LearnContentList[i].Answer" >
<ejs-richtexteditor id="test_@i" value="@Model.LearnContentList[i].Answer" >