A product I've inherited is using WebClient to read HTML from a MVC based site. Each page is a different type of e-mail, so in order to compose and send an e-mail they use WebClient to request a URL and download the string.
var outputHtml = string.Empty;
using (WebClient client = new WebClient())
{
client.Encoding = Encoding.UTF8;
outputHtml = client.DownloadString(emailURL);
}
return outputHtml;
Is there a way to remove the need to host this email based site but retain most of this code. I guess what I need to do is pass my request to the controller and retrieve the output after the razor engine has passed the view model through the cshtml page.
Is that possible?
There are many ways you could render a Razor view to a string. One possibility is to use RazorEngine. Another possibility is to use some specifically designed framework for this purpose such as Postal.
Related
I have an ASP.NET MVC 5 website. I have used action link while designing table to display a list of data. while navigating from that action link I have passed a class object as a parameter. After visiting that link, it parses that object parameter as long query string which exposes data in the URL.
What is the way to handle a query string in MVC?
Is it possible to hide query string or way to pass an object as a parameter without exposing it in the URL?
You can not hide the query string, it is part of the URL. You could encrypt it tho.
One solution would be to use a POST request instead of a GET. Then you can send the data in the body of the request, it will not show up in the URL. But it will still be accessible if you inspect the network traffic (e.g. if you run Fiddler on the client computer).
Another solution would be to still use a GET request, but instead of passing all the data, just pass an ID, then load the data again from the database using this ID. Note that this ID can be spoofed too, so make sure the User has actually the permissions to request this ID.
#Html.ActionLink("Show details", "Details", "Data", new { dataId = Model.Id })
[HttpGet]
public ActionResult Details(long dataId) {
var data = _dbContext.Data.Find(dataId);
var vm = new DataDetailsViewModel(data);
return View("Details", vm);
}
I need to develop a payment gateway web service which can be called from all my other application.I use ASP.net web API for this.
I created an HTTP post service which accepts XML as an input parameter.I will parse this XML.if there is sufficient information it will be redirected to payment page or otherwise it will show a page which collects the sufficient data from user. So it must return a view to user and custom error codes and messages.
These are my needs and I want to know which is the best way to accomplish this.
Can I use web API controller or MVC controller for this?
How will the client show the view returned? Inside iframe is not considered as a good choice for me.Is there any other good ways to show the page?
You can use RazorEngine to parse view in WebApi.
var templatePath = HttpContext.Current.Server.MapPath("~/Views/Payment/Form.cshtml");
var templateContent = File.ReadAllText(templatePath);
var templateString = Razor.Parse(templateContent, new ClassA());
return Ok(new {
ErrorCode = "000",
Html = templateString
});
Your can refer this link https://antaris.github.io/RazorEngine/ for quickstart.
I know it is possible to render a MVC Action to string from another controller within the MVC project, but instead I need to invoke the rendering from a class that does not provide a HttpContext.
In fact it is a inherited class from a SignalR.Hub class.
The basic idea is to pass a rendered ActionResult/View string to all clients via SignalR.
Thanks for your time!
You could send an HTTP request to the controller action in question:
using (var client = new WebClient())
{
string html = client.DownloadString("http://example.com/controller/action");
// TODO: broadcast the html to all connected clients
}
I want a partial view that display some stuff from a website that is not under my control.
The data on the website is only available through HTML, and thus I can only retrieve it by querying the web site and parsing the HTML. (The website holds a list of 50 elements, and I only want the top 10.)
Now, the data from the website is not changing very frequently, so I imagine that I can retrieve the HTML on an hourly basis, and displaying a cached version on my web site.
How can I accomplish this in ASP.NET MVC 3?
Ignoring the MVC3 requirement for now, you should look to using WebClient to grab the html from the website. You can do something like:
var client = new WebClient();
var html = Encoding.UTF8.GetString(client.DownloadData("http://www.somedomain.com"));
If you need to tailor your request, I'd recommend looking at HttpWebRequest, HttpWebResponse. Now that you can grab the html, you need to consider your caching mechanism, possibly in the ASP.NET runtime?
public ActionResult GetHtml()
{
if (HttpRuntime.Cache["html"] == null)
GetHtmlInternal();
return Content((string)HttpRuntime.Cache["html"], "text/html");
}
private void GetHtmlInternal()
{
var html = // get html here.
HttpRuntime.Cache.Insert("html", html, null, DateTime.Now.AddMinutes(60), Cache.NoSlidingExpiration);
}
The first solution that comes to mind is to create an action in a controller that makes an Http request to the remote web page and parses the html you want to return to your own page and then set output caching on your action.
Edit:
What controller to put the action in would depend on the structure of your web site and whether the partial view would be visible on all views or just a specific view. If the partial is visible in all views I'd either place it in the Home controller or create a "General" controller (if I anticipated more actions would go in such a controller).
If you want to manipulate the result I would probably make a model and partial view for the list. If you want to take a part of the returned html and output it as it is I would use the same method as in the answer by Matthew Abbott:
return Content(yourHtmlString);
The end would look something like this:
[OutputCache(Duration = 3600)]
public ActionResult RemoteList()
{
var client = new WebClient();
var html = Encoding.UTF8.GetString(client.DownloadData("http://www.somedomain.com"));
// Do your manipulation here...
return Content(html);
}
(Some of the above code was borrowed from the post by Matthew Abbott.)
You could just add OutputCache attribute on your action and set OutputCache.Duration Property to 3600 seconds (1 hour)
I have an ActionResult in my controller that I want to send an HTML email from, the body of that email is generated by a view. Rather than having 2 actionresults methods in my controller can I just get the result of the view when passed my model and avoid it being sent to the browser?
MvcMailer is a brilliant little project that supports generating emails using MVC views. It is available as a NuGet package.
In order to render a view to a string instead of response use this code (relativePath points to your view file):
var content = string.Empty;
var view = ViewEngines.Engines.FindView(ControllerContext, relativePath, null);
using (var writer = new StringWriter())
{
var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
view.View.Render(context, writer);
writer.Flush();
content = writer.ToString();
}
Take a look at the open source Postal project it's available view NuGet.
Postal lets you create emails using regular MVC views.
Andrew Davey done a presentation on Generating email with View Engines using Postal at mvcConf 2
Or alternatively this blog post shows you a simple way.