I have some encoded Html which have any number of 1000s of different Razor variables embedded within it that I have stored and need to retrieve from the database. I want to be able to render this in a MVC/razor view.
Just one simple example of the html saved on the database (it can be more complex):
"<span>Your page is #Config.PageColour and you have page size of #Config.PageSize</span>"
MessageController.cs
public ActionResult ShowMessage()
{
var htmlToDisplay = _messageDAL.getHtmlMessage();
var messageVm = new MessageVm
{
DisplayMessage = htmlToDisplay;
};
return View("Index.cshtml", "", messageVm);
}
Index.cshtml
<html>
#Html.Raw(#model.DisplayMessage)
</html>
Results
When I run this the rendered page looks like this:
Your page is #Config.PageColour and you have page size of #Config.PageSize
But I want it to interpret the value of the Razor variable with the html block and should look like this:
Your page is Blue and you have page size of A4
Really stuck on this so any help would be appreciated!
Use this line. I hope this may help.
#Html.Raw(System.Web.HttpUtility.HtmlDecode(#model.DisplayMessage))
EDIT 1
You can use any Razor Compiler like the one mentioned below
RazorEngine:
string result = RazorEngine.Razor.Parse(#model.DisplayMessage, new { Name = "Name" });
RazorEngine does not support any of the Mvc helpers such as Html and Url. Since these libraries are supposed to exist outside of Mvc and thus require more work to get them to work with those helpers.**
EDIT 2
You can use a Razor compiler that allows you to use HTML templates called RazorEngine which can be found at https://github.com/Antaris/RazorEngine
From Visual Studio, using the Package Manager Console command:
Install-Package RazorEngine
After installation I changed my controller as follows:
MessageController.cs
public ActionResult ShowMessage()
{
var htmlTemplate = _messageDAL.getHtmlMessage();
var htmlToDisplay = Engine.Razor.RunCompile(htmlTemplate , "messageTemplateKey", null, new { Name = "some model data" });
var messageVm = new MessageVm
{
DisplayMessage = htmlToDisplay;
};
return View("Index.cshtml", "", messageVm);
}
You can use a Razor compiler that allows you to use HTML templates called RazorEngine which can be found at https://github.com/Antaris/RazorEngine
From Visual Studio, using the Package Manager Console command:
Install-Package RazorEngine
After installation I changed my controller as follows:
MessageController.cs
public ActionResult ShowMessage()
{
var htmlTemplate = _messageDAL.getHtmlMessage();
var htmlToDisplay = Engine.Razor.RunCompile(htmlTemplate , "messageTemplateKey", null, new { Name = "some model data" });
var messageVm = new MessageVm
{
DisplayMessage = htmlToDisplay;
};
return View("Index.cshtml", "", messageVm);
}
And it worked first time. Big thanks to #Mukesh Kumar who provided the vital clues to rewrite the code which I've posted as a complete and working answer here.
Related
In my MVC C# project (NOT THE CORE) i used this successfully:
Index.cshtml:
<script>
#{
var ListVar = Model.TimeToolDataList;
//TimeToolDataList (*it's an object list, ex: NAME = string, VALUE = int)
var SerializedList = new JavaScriptSerializer().Serialize(ListVar);
}//razer code in the script tag ^ by the #{} wrapper
var SerializedListRefined = JSON.parse('"#SerializedList"');
var FinalList = JSON.parse(htmlDecode(SerializedListRefined));</script>
great!!! i can console.log the list and 'see' it's contents, what is the equivalent of this code for ASP.NET CORE project? because when i copy/pasted *along with all the other stuff, it wont run!!!
This cant be used: JavaScriptSerializer()
This cant be used either: JSON.parse(htmlDecode(SerializedListRefined));
Update, instead of JavaScriptSerializer() , this worked:
var jsonStr = JsonSerializer.Serialize(ListVar);
^under #using System.Text.Json;
when running, the console on the browser gives me an 'Uncaught ReferenceError: htmlDecode is not defined' error
try something like the next
to deserialize the object correclty you have to use #HtmlRaw just assuming ListVar is your Model/Object (the object comming from the c# controller)
you can do the next :
var jsoninJS = #Html.Raw(Json.Serialize(Listvar));
that gives you in your var jsoninJS the object that you can print with Console.log(jsoninJS) in javascript.
if you include
#using System.Web you can also decode with C#
using #HttpUtility.HtmlDecode(string)
but you should decode/encode on you print the data, not anywhere else.
I have an ASP.NET app. My app has a _ViewStart.cshtml file. That file looks like this:
#using MyCompany.MyApp;
#{
Layout = "/Views/Shared/_Layout.cshtml";
var p = HttpContext.Current.Request.QueryString["parameter"];
ViewBag.QSParameter = p;
}
When I execute this code, I get the following error:
The name 'HttpContext' does not exist in the current context
I don't understand. Isn't _ViewStart.cshtml kind of the "shell" for the views? I'm trying to figure out how to globally read a query string parameter and set a value on the ViewBag for each request. I thought this would be the way to do it.
Thanks
You should have access to Request in your _ViewStart file.
Try this:
#using MyCompany.MyApp;
#{
Layout = "/Views/Shared/_Layout.cshtml";
var p = Request.QueryString["parameter"];
ViewBag.QSParameter = p;
}
EDIT: For ASP.NET 5
I don't have ASP.NET 5 on my machine but have looked at the source code for the framework. It looks like there is a Context property on RazorPage that returns an HttpContext. Alternatively, you can access the HttpContext through the ViewContext. See below:
#{
Layout = "/Views/Shared/_Layout.cshtml";
var p = Context.Request.Query["parameter"];
// or this...
// var p = ViewContext.HttpContext.Request.Query["parameter"];
ViewBag.QSParameter = p;
}
To retrieve it from _ViewStart.cshtml, you can use:
ViewBag.QSParameter = Context.Request.Query["parameter"];
Note: Use Query now (over QueryString) in ASP.NET 5
However, I might ellect to go a different route and take advantage of IResultFilter:
public class QSParameterFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
var QSParameter = context.HttpContext.Request.Query["parameter"];
((Controller)context.Controller).ViewBag.QSParameter = QSParameter;
}
public void OnResultExecuted(ResultExecutedContext context) { }
}
Then, register it within your Startup.cs:
services.AddMvc();
services.Configure<MvcOptions>(options => {
options.Filters.Add(new QSParameterFilter());
});
Make the "Build Action = Content" in the file properties. This will solve the issue.
I´m trying to get single value out of an object array and display it for now inside paragraph tag on my index page.
In my HomeController I have done this
public ActionResult Index()
{
WebClient client2 = new WebClient();
Stream stream = client2.OpenRead("http://localhost/ARN/weatherAPI.json");
StreamReader reader = new StreamReader(stream);
Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
// instead of WriteLine, 2 or 3 lines of code here using WebClient to download the file
var weatherString = (string)jObject["weather"][0]["main"];
stream.Close();
return View();
I started by creating a new project in Console Application to test it and I ran this lines of code but used Console.Writeline(weatherString) and it gave me exactly the value I needed in the console but now I'm facing the problem to try to show it on the index page with the ASP.NET MVC
Since this piece of code is in my HomeController and my Index.cshtml is elsewhere, is there an easy way for me to output the weatherString variable as an simple text on my index page?
The JSON looks like this:
"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}]
So I wan't "Rain" to be outputted on my webpage.
You'll probably want it in your ViewBag. In the controller:
ViewBag.WeatherString = weatherString;
then in the view access it with #ViewBag.WeatherString
Alternatively you can use it as the view's model:
return View(weatherString)
and in your view:
model string
but thats pretty overkill
I am using #Html.Action to call contoller action to return a string. I want to save the string to a variable inside razor as it is comma-seperated.
#Html.Action("GetCategories", new { SP = #ViewBag.Name, SD = "Cad" }).ToString();
//#String s = save above string in here
//#string[] arrS = s.Split(',');
#String test = #Html.Action(......) //tried this but does NOT work.
Public ActionResult GetCategories(string SP, string SD)
{
//Code missing
return Content(return "sugar");
}
How can I save the Html.Action returned data to a string ?
This works for me, just tried in a local MVC project:
#{
string test;
test = #Url.Action("actionName");
}
Url.Action only/always returns a Url. Not sure how this selected answer solved the problem for you unless you DID want the Url (e.g. /Controller/Action/...).
Seems Html.Action was what you wanted all along. It would return the contents "sugar" if you simply had your return coded like this;
return Content("sugar");
You can display it right on the page or use the suggested syntax from "Mark" to save it to a varible
I want to write a little helper function that returns the site url.
Coming from PHP and Codeigniter, I'm very upset that I can't get it to work the way I want.
Here's what I'm trying:
#{
var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
var baseurl = urlHelper.Content("~");
}
<script>
function base_url(url) {
url = url || "";
return '#baseurl' + url;
}
</script>
I want to return the base url of my application, so I can make ajax calls without worrying about paths. Here's how I intend to use it:
// Development
base_url(); // http://localhost:50024
// Production
base_url("Custom/Path"); // http://site.com/Custom/Path
How can I do something like that?
EDIT
I want absolute paths because I have abstracted js objects that makes my ajax calls.
So suppose I have:
function MyController() {
// ... js code
return $resource('../MyController/:id');
}
// then
var my_ctrl = MyController();
my_ctrl.id = 1;
my_ctrl.get(); // GET: ../MyController/1
This works when my route is http://localhost:8080/MyController/Edit but will fail when is http://localhost:8080/MyController .
I managed to do it like this:
#{
var url = Request.Url;
var baseurl = url.GetLeftPart(UriPartial.Authority);
}
Thank you all!
Are you aware of #Url.Action("actionname") and #Url.RouteUrl("routename") ?
Both of these should do what you're describing.
Instead of manually creating your URL's, you can use #Url.Action() to construct your URLs.
<p>#Url.Action("Index", "Home")</p>
/Home/Index
<p>#Url.Action("Edit", "Person", new { id = 1 })</p>
/Person/Edit/1
<p>#Url.Action("Search", "Book", new { title = "Gone With The Wind" })</p>
/Book/Search?title="Gone+With+The+Wind"
Now the absolute best reason to go with this option is that #Url.Action automatically applies any vanity URL routes you have defined in your Global.asax file. DRY as the sub-saharan desert! :)
In your case, your can create a 'custom path' in two ways.
Option A)
<p>#Url.Action("Path", "Custom")</p>
/Custom/Path
Option B)
You can create a route using the Global.asax file. So your controller/action combo can be anything you want, and you can create a custom vanity route url - regardless of the controller/action combo.