How to fetch content from namespace "Microsoft.AspNetCore.Mvc.Razor.HelperResult" - razor

In ASP.NET Core, I need to fetch the content value from the namespace Microsoft.AspNetCore.Mvc.Razor.HelperResult and assign the value in a variable but its assigning the namespace to that variable.
It works fine in MVC when i use namespace System.Web.WebPages.HelperResult and assign that content to variable. (Content are some html elements).
Please, check the picture to find the issue.
My code:
Variable with namespace name as value

In .NET Core HelperResult returns IHtmlContent instead of IHtmlString.
For IHtmlContent it might be convenient to use an extension like the one mentioned here:
public static IHtmlContent GetList(this IHtmlHelper helper)
{
var listHtml = new HtmlContentBuilder();
listHtml.AppendHtml("<ol><li>");
listHtml.AppendHtml(helper.ActionLink("foo", "bar", "example"));
listHtml.AppendHtml("</li></ol>");
return listHtml;
}

Try this (since HelperResult implements IHtmlContent interface):
public static string ToHtmlString(this IHtmlHelper source, IHtmlContent htmlContent)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
{
var encoder = (HtmlEncoder)source.ViewContext.HttpContext.RequestServices.GetService(typeof(HtmlEncoder));
htmlContent.WriteTo(tw, encoder);
}
return sb.ToString();
}
and call this method in your Razor view like this:
#Html.ToHtmlString(helperResultObject)

Related

ASP.NET MVC DataBinder not deserializing simple types from JSON

Input JSON:
{ "name": "gerry" }
Action method:
{ public ActionResult GenerateQrCode([FromBody] string name }
Problem:
The simple-type args are null
ModelState: Invalid
The built-in json deserializer can't handle the input in this form
I've tried:
ConfigureServices() -> services.AddControllersWithViews().AddNewtonsoftJson(); to switch to NewtonSoft, which I know/love
I've set a break-point into the non-NewtonSoft built-in MS SystemTextJsonInputFormatter.ctor() just to check, if it's still used: yes, it is, I'm not sure why, when I'm calling the above .AddNewtonsoftJson()
The situation:
The client POSTs all the input params as one JSON string document, which is UTF8 w/out BOM
The string comes in at the server-side and is nicely readable with new System.IO.StreamReader(Request.Body).ReadToEnd() from inside the immediate window
I need a way ASP.NET Core deserializes this, as it was able under the .NET4.X for many years w/out any issue
I wouldn't like to add [FromBody] and similar opt-in signatures all over the server actions/args
You pass the name as json but accept as a string so it will be null, you can use an InputFormatter like:
public class RawJsonBodyInputFormatter : InputFormatter
{
public RawJsonBodyInputFormatter()
{
this.SupportedMediaTypes.Add("application/json");
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
var request = context.HttpContext.Request;
using (var reader = new StreamReader(request.Body))
{
var content = await reader.ReadToEndAsync();
return await InputFormatterResult.SuccessAsync(content);
}
}
protected override bool CanReadType(Type type)
{
return type == typeof(string);
}
}
In startup.cs:
services
.AddMvc(options =>
{
options.InputFormatters.Insert(0, new RawJsonBodyInputFormatter());
});
And then you can get the row string
To deserilize it, you can check this, use Newtonsoft and make the string to a Model
[HttpPost]
public IActionResult GenerateQrCode([FromBody] string name)
{
object o = JsonConvert.DeserializeObject(name);
MyModel my = JsonConvert.DeserializeObject<MyModel>(o.ToString());
return View();
}

Adding a dynamic list of parameters with Html helper

I'd like to be able to feed in a list of parameter names and values into a Html.Actionlink but the helper doesn't create the parameters as I would like. Any ideas how to do this?
public class ParameterNameValue
{
public string ParameterName { get; set; }
public string ParameterValue { get; set; }
}
View
#foreach (var action in post.FeedActions)
{
var parameters = "";
foreach (var param in action.Parameters)
{
parameters += param.ParameterName + "=" + param.ParameterValue + ",";
}
#Html.ActionLink(#action.Label, action.ActionName,
new { controller = action.Controller, id = action.CommunityId, slug = action.Slug,
Fromfeed=true,parameters }, new { #class = action.Classes })
}
yields a link like this:
Whereas I need the parameters part to look like:
?FromFeed=true&MatchId=1234&InnerId=5678
edit: I got it working by just manually creating the tag, but no doubt there's a nice way of doing this by creating a custom helper.
#action.Label
I'd suggest you to extend the classic ActionLink helper with a prototype similar to this (add a parameter for your specific class) :
public static MvcHtmlString ActionLinkCustom(this HtmlHelper html, string linkText, string actionName, string controllerName, object routeValues, List<ParameterNameValue> yourOtherValues)
In the code, check if you got any custom values. If such, add them to the RouteValuesDictionnary. Then use the classic ActionLink helper providing this modified RouteValuesDictionnary.
Note : you can work on the routeValues using this
IDictionary<string, object> RouteValues = HtmlHelper.ObjectToDictionary(routeValues);

how can i deep clone a list<T> in windows phone 8.1 without icloneable interface?

I want to deep clone a generic list but icloneable interface is not present in windows phone 8.1 also binaryformatter class is also not present?
Try this
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
Your class MUST be marked as [Serializable] in order for this to work.
Your source file must include the following code:
If you want clone all members and then refer this Deep Copy of Object in C#
You can create your own icloneable interface and define a function as follows:
public interface IClonable<T>
{
T Clone();
}
public static T[] Clone<T>(this T[] origin) where T : IClonable<T>
{
return origin.Select(x => x.Clone()).ToArray();
}

How to get ITemplate from razor engine (IRazorEngineService)

I just updated our RazorEngine reference to version 3.7.5. A bunch of things seems to have changed and became obsolete.
For most things I figured out 'the new way', except for 1 thing: getting an ITemplate instance.
We used to use a TemplateService instance. That had a method Resolve, which returns an ITemplate instance.
The TemplateService was replaced with IRazorEngineService. This doesn't have any method returning an ITemplate.
What's the correct way to retrieve one?
As I already discussed this on some threads here some quotes:
Can you elaborate the reasons why you need access to instances of that interface directly?
I decided to remove direct access to it as it isn't easy to use and mostly doesn't do what you think it does. It also can cause problems in case you use the Isolation API.
https://github.com/Antaris/RazorEngine/issues/225
If its about setting custom layouts the proper upgrade path is to use a custom TemplateBase and make use of the ViewBag (as discussed on the linked issue).
The other more interesting use case is to get data OUT of the template.
This is discussed in detail here: https://github.com/Antaris/RazorEngine/issues/238
Here is a code sample on how to get out the 'Subject' from the given template
Template:
#model HelloWorldModel
#{
Layout = "CI";
Subject = "Hello World";
}
Hello #Model.Name,<br/>
this is a test email...
Code (simplified)
class CustomDataHolder {
public string Destination { get; set; }
public string Subject { get; set; }
}
// In the custom TemplateBase class:
public string Subject { get { return Viewbag.DataHolder.Subject; }; set { Viewbag.DataHolder.Subject = value; } }
// Your code
public static Task SendEmailAsync<T>(string templateName, string destination, T model)
{
var holder = new CustomDataHolder ();
dynamic viewbag = new DynamicViewBag();
viewbag.DataHolder = holder;
holder.Destination= destination;
var body = Engine.Razor.Run(templateName, typeof(T), model, (DynamicViewBag)viewbag);
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress(holder.Destination));
msg.Subject = holder.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html));
SmtpClient smtpClient = new SmtpClient();
return smtpClient.SendMailAsync(msg);
}
Hope this covers your use case. Otherwise please add more information to your question on what you trying to achieve with the ITemplate instances....

render the view using razorengine mvc

I am using RazorEngine to get the view and load it as html.but however my problem is I am reading html code from my database,and show it on my web page .but it gave me string result on my web page rather then html output.
how can I solve this problem
thank you in advace
My simple view like this
#model Cms.ViewModules.MasterPageViewModel
#Model.PageLanguageViewModel.HtmlCode
and this is how get the view as html from my views
public static class HtmlHelperPageContent
{
public static IHtmlString GetPageAll(this HtmlHelper htmlHelper, MasterPageViewModelmodel)
{
string page = model.PageLanguageViewModel.SablonHtlmCodu;
List<string> registeredModules = PageModulles.RegisteredModules;
foreach (var modulename in registeredModules )
{
string fullmodulename = "${" + modulename + "}";
if (page.Contains(fullmodulename ))
{
string viewname = modulename.Insert(0, "PW_");
IHtmlString value = RenderViewHelper.RenderPartialToString("Views/Default/" + viewname + ".cshtml", model);
page=page.Replace(fullmodulename , value.ToHtmlString());
}
}
return MvcHtmlString.Create(page);
}
RenderViewHelper class
public static class RenderViewHelper
{
public static IHtmlString RenderPartialToString(string viewPath, object model)
{
string viewAbsolutePath = MapPath(viewPath);
var viewSource = File.ReadAllText(viewAbsolutePath);
string renderedText = Razor.Parse(viewSource, model);
return new MvcHtmlString(renderedText);
}
}
Another way would be to use IEncodedString (https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Text/IEncodedString.cs) instead of IHtmlString by creating a RawString (https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Text/RawString.cs) instance.
#Raw does exactly that behind the scenes (https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Templating/TemplateBase.cs#L147).
#Raw(#Model.PageLanguageViewModel.HtmlCode) solved my problem