Unable to add BarCode in 'cshtml' using TagHelper in ASP.NET core 2.0 class project - razor

I'm using here TagHelper concept in ASP.Net core 2.0 class library.
using Microsoft.AspNetCore.Razor.TagHelpers;
using ZXing.QrCode;
using System.Drawing;
using System.IO;
using System;
namespace DRC.Taxpayer.TagHelpers
{
[HtmlTargetElement("barcode")]
public class BarCodeTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var content = context.AllAttributes["content"].Value.ToString();
var width = int.Parse(context.AllAttributes["width"].Value.ToString());
var height = int.Parse(context.AllAttributes["height"].Value.ToString());
var barcodeWriterPixelData = new ZXing.BarcodeWriterPixelData
{
Format = ZXing.BarcodeFormat.CODE_128,
Options = new QrCodeEncodingOptions
{
Height = height,
Width = width,
Margin = 0
}
};
var pixelData = barcodeWriterPixelData.Write(content);
using (var bitmap = new Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb))
{
using (var memoryStream = new MemoryStream())
{
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, pixelData.Width, pixelData.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
try
{
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
output.TagName = "img";
output.Attributes.Clear();
output.Attributes.Add("width", width);
output.Attributes.Add("height", height);
output.Attributes.Add("src", string.Format("data:image/png,base64,{0}", Convert.ToBase64String(memoryStream.ToArray())));
}
}
}
}
}
In CSHTML I've added below tag helpers:
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers;
#addTagHelper *, BarCodeTagHelper;
To set barCode in cshtml (using razor engin i.e. RazorEngine.Core.NetCore, I've added below a line of code:
But when I execute the application, it is not considering the tag helper and keeping it as a blank.
Am I doing something wrong in this?
Is it the correct approach I'm using here to generate barcode? Is there any other way to do it in ASP.Net core 2.0?
I have tried implementing the solution provided in this answer but it is not working for me.

Related

Razor Pages and Json

I am developing an application that consults a Web API from an affiliate website, gets data in json format and I want to simply present this data in a page.
public async Task<IActionResult> OnPostAsync(string urljson)
{
var httpClient = new HttpClient();
var resultado = await httpClient.GetStringAsync(urljson);
Produto.Rootobject Produtos = JsonConvert.DeserializeObject<Produto.Rootobject>(resultado);
return RedirectToPage("ListaSugestoes", Produtos);
}
The code I added in the page I want the results to appear is:
using Buyit.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Buyit.Pages
{
public class ListaSugestoesModel : PageModel
{
private readonly Produto.Rootobject _jsonProdutos;
public ListaSugestoesModel(Produto.Rootobject jsonProdutos)
{
_jsonProdutos = jsonProdutos;
}
public JsonResult OnGetProdutos()
{
return new JsonResult(_jsonProdutos);
}
}
}
Is it done right? I had it work using a Controller, but I am trying to learn Razor Pages and want to know if that's possible to implement using it. Tks!

compilation.Emit(..) create typeOf(T) with constructor params

I'm using RazorEngine for Razor Template parsing and trying to make use of its Roslyn code.
I know my issue is that I'm using a base-type (ViewBase<t>) in my razor views, and it's not being constructed (As it has a ctor parameter).
However after much googling, I can't find a way to tell Emit() how to make an instance of my type.
Below is the code it uses - the source code generates fine, and an omitted version is included below.
Is there some sort of factory of some sort I can provide in which it can use to generate this type?
When I call emit I get the error There is no argument given that corresponds to the required formal parameter 'componentContext' of 'ViewBase<MyModelType>.ViewBase(IComponentContext)' - So how would I tell emit() how to create a instance of my type ViewBase<T>
Creating an empty CTOR works fine - but isn't what I require.
public override Tuple<Type, CompilationData> CompileType(TypeContext context)
{
var sourceCode = GetCodeCompileUnit(context);
var assemblyName = GetAssemblyName(context);
(new PermissionSet(PermissionState.Unrestricted)).Assert();
var tempDir = GetTemporaryDirectory();
var sourceCodeFile = Path.Combine(tempDir, String.Format("{0}.{1}", assemblyName, SourceFileExtension));
File.WriteAllText(sourceCodeFile, sourceCode);
var references = GetAllReferences(context);
var compilation =
GetEmptyCompilation(assemblyName)
.AddSyntaxTrees(
GetSyntaxTree(sourceCode, sourceCodeFile))
.AddReferences(GetMetadataReferences(references));
compilation =
compilation
.WithOptions(
CreateOptions(context)
.WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
.WithPlatform(Platform.AnyCpu)
.WithSourceReferenceResolver(new RazorEngineSourceReferenceResolver(sourceCodeFile)));
var assemblyFile = Path.Combine(tempDir, String.Format("{0}.dll", assemblyName));
var assemblyPdbFile = Path.Combine(tempDir, String.Format("{0}.pdb", assemblyName));
var compilationData = new CompilationData(sourceCode, tempDir);
using (var assemblyStream = File.Open(assemblyFile, FileMode.Create, FileAccess.ReadWrite))
using (var pdbStream = File.Open(assemblyPdbFile, FileMode.Create, FileAccess.ReadWrite))
{
var opts = new EmitOptions()
.WithPdbFilePath(assemblyPdbFile);
var pdbStreamHelper = pdbStream;
if (IsMono())
{
opts = opts.WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
}
var result = compilation.Emit(assemblyStream, pdbStreamHelper, options: opts);
}
}
My generated view code
namespace CompiledRazorTemplates.Dynamic
{
#line default
#line hidden
;
using System;
//my load of other using statements...
public class RazorEngine_99d043dd3e3d4c3ca787d42dd7a0bb6b : ViewBase<MyModelType>
{
#line hidden
public RazorEngine_99d043dd3e3d4c3ca787d42dd7a0bb6b()
{
}
#pragma warning disable 1998
public override async Task Execute()
{
..... OMITTED
}
}
}
public ViewBase(IComponentContext componentContext)
{
Contract.Requires(componentContext != null);
_componentContext = componentContext;
}
You're asking about the Razor compiler, not about Roslyn compilation.
I don't think there is any way to do that.
However, you could use a Roslyn CSharpSyntaxRewriter to find the existing constructor in your SyntaxTree and rewrite it to have & pass a parameter.

Saving an MVC View to PDF

As the title suggests, I am looking for a way to export a .NET MVC View to a PDF.
My program works like this:
Page 1
Takes in information
Page 2
Takes this information and heavily styles it with CSS etc
So basically I need to save page 2 after it has been processed and used the information from Page 1's model.
Thanks in advance!
To render a non-static page to a pdf, you need to render the page to a string, using a ViewModel, and then convert to a pdf:
Firstly, create a method RenderViewToString in a static class, that can be referenced in a Controller:
public static class StringUtilities
{
public static string RenderViewToString(ControllerContext context, string viewPath, object model = null, bool partial = false)
{
// first find the ViewEngine for this view
ViewEngineResult viewEngineResult = null;
if (partial)
{
viewEngineResult = ViewEngines.Engines.FindPartialView(context, viewPath);
}
else
{
viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
}
if (viewEngineResult == null)
{
throw new FileNotFoundException("View cannot be found.");
}
// get the view and attach the model to view data
var view = viewEngineResult.View;
context.Controller.ViewData.Model = model;
string result = null;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
view.Render(ctx, sw);
result = sw.ToString();
}
return result.Trim();
}
}
Then, in your Controller:
var viewModel = new YourViewModelName
{
// Assign ViewModel values
}
// Render the View to a string using the Method defined above
var viewToString = StringUtilities.RenderViewToString(ControllerContext, "~/Views/PathToView/ViewToRender.cshtml", viewModel, true);
You then have the view, generated by a ViewModel, as a string that can be converted to a pdf, using one of the libraries out there.
Hope it helps, or at least sets you on the way.

How to do Dynamic URL Redirect in ASP.net MVC?

I have to get html response from another website and load to my application. I written below code,
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
namespace MVC_TEST.Controllers
{
public class DocumentCloudController : Controller
{
public string Index()
{
var result = GetResponse();
return result;
}
private static string GetResponse()
{
var html = string.Empty;
const string url = #"http://localhost/xxxxx/yyyyy/logon.aspx";
var request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}
}
}
}
return html;
}}
}
}
Controls are loaded properly, But image, css and js path is mapped to relative path
/xxxx/yyyy/dojo.js ,
/xxxx/style/logon.css,
/xxxx/images/logon.png
in html, here i have to change that to actual url like below
http://localhost/xxxx/yyyy/dojo.js ,
http://localhost/xxxx/style/logon.js ,
http://localhost/xxxx/images/logon.png
One option is find these content in html replace that.
Is there any other option to change url dynamically ?
Is IIS URL Rewrite module will suitable for my requirement ?
Please share your thoughts
Using IIS URL Rewrite Module could work but I would recommend using a HTML parser like HTML Agility Pack or AngleSharp to query and manipulate the DOM.
The example below is a snippet that worked for me when creating a reverse proxy:
foreach (var link in document.DocumentNode.SelectNodes("//link[#href]"))
{
var orgHrefValue = link.GetAttributeValue("href", string.Empty);
var updHrefValue = string.Concat("[BASE URL]", GetAbsoluteUrlString(requestedUrl, orgHrefValue).AbsoluteUri);
link.SetAttributeValue("href", updHrefValue);
}
private static Uri GetAbsoluteUrlString(string baseUrl, string url)
{
var uri = new Uri(url, UriKind.RelativeOrAbsolute);
if (!uri.IsAbsoluteUri)
uri = new Uri(new Uri(baseUrl), uri);
return uri;
}

vNext: Console app that uses razor views without hosting

I am creating console application that does some file conversions. These conversions are easily done creating a model from the input file and then executing razor models for the output.
To have this working in the IDE I used Visual Studio 2015 preview and created a vnext console application that uses MVC. (You get razor support out of the box then). To get this all working you need to host the MVC app though, and the cheapest way to do that is hosting is through a WebListener. So I host the MVC app and then call it through "http://localhost:5003/etc/etc" to get the rendered views that construct the output.
But the console app is not supposed to listen to/use a port. It is just a command line tool for file conversions. If multiple instances would run at the same time they would fight to host the pages on the same port. (This could of coarse be prevented by choosing a port dynamically, but this is not what I am looking for)
So my question is how would you get this working without using a port, but using as much of the vnext frameworks as possible.
In short: how can I use cshtml files that I pass models in a console app that does not use a port using the vnext razor engine.
Here is some code I currently use:
Program.cs
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace ConsoleTest
{
public class Program
{
private readonly IServiceProvider _hostServiceProvider;
public Program(IServiceProvider hostServiceProvider)
{
_hostServiceProvider = hostServiceProvider;
}
public async Task<string> GetWebpageAsync()
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://localhost:5003/home/svg?idx=1");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
return await httpClient.GetStringAsync("");
}
}
public Task<int> Main(string[] args)
{
var config = new Configuration();
config.AddCommandLine(args);
var serviceCollection = new ServiceCollection();
serviceCollection.Add(HostingServices.GetDefaultServices(config));
serviceCollection.AddInstance<IHostingEnvironment>(new HostingEnvironment() { WebRoot = "wwwroot" });
var services = serviceCollection.BuildServiceProvider(_hostServiceProvider);
var context = new HostingContext()
{
Services = services,
Configuration = config,
ServerName = "Microsoft.AspNet.Server.WebListener",
ApplicationName = "ConsoleTest"
};
var engine = services.GetService<IHostingEngine>();
if (engine == null)
{
throw new Exception("TODO: IHostingEngine service not available exception");
}
using (engine.Start(context))
{
var tst = GetWebpageAsync();
tst.Wait();
File.WriteAllText(#"C:\\result.svg", tst.Result.TrimStart());
Console.WriteLine("Started the server..");
Console.WriteLine("Press any key to stop the server");
Console.ReadLine();
}
return Task.FromResult(0);
}
}
}
Startup.cs
using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.ConfigurationModel;
namespace ConsoleTest
{
public class Startup
{
public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
// Add MVC services to the services container
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
//Configure WebFx
app.UseMvc(routes =>
{
routes.MapRoute(
null,
"{controller}/{action}",
new { controller = "Home", action = "Index" });
});
}
}
}
I solved it using the following code:
Program.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.TestHost;
using Microsoft.AspNet.Builder;
using Microsoft.Framework.Runtime.Infrastructure;
namespace ConsoleTest
{
public class Program
{
private Action<IApplicationBuilder> _app;
private IServiceProvider _services;
public async Task<string> TestMe()
{
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
return await client.GetStringAsync("http://localhost/home/svg?idx=1");
}
public void Main(string[] args)
{
_services = CallContextServiceLocator.Locator.ServiceProvider;
_app = new Startup().Configure;
var x = TestMe();
x.Wait();
Console.WriteLine(x.Result);
Console.ReadLine();
}
}
}
Startup.cs
using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Routing;
namespace ConsoleTest
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseServices(services =>
{
// Add MVC services to the services container
services.AddMvc();
});
//Configure WebFx
app.UseMvc(routes =>
{
routes.MapRoute(
null,
"{controller}/{action}",
new { controller = "Home", action = "Index" });
});
}
}
}