How to send my view by email with my controller? - asp.net-mvc

I'm a beginner in ASP.net MVC and I have a problem when I want to send my view by email with my controller.
I do not arrive to send it, I just arrive send some text
About what I have already tried, I'm gonna show you with the code.
(If my problem is not understandable tel me and I explain differently)
// Page MailHelper.cs
// The tools for sending mail
public static void SendMail(string body)
{
try
{
var mailto = ConfigurationManager.AppSettings["mailto"].Split(';');
MailMessage mail = new MailMessage();
mail.IsBodyHtml = true;
SmtpClient SmtpServer = new SmtpClient();
mail.From = new MailAddress("SendVersionsRobot#trysomething.fr");
foreach (var m in mailto)
mail.To.Add(m);
mail.Subject = "try send Mail";
mail.Body = body;
SmtpServer.Send(mail);
}
catch (Exception ex)
{
}
}
// Page MailController.cs
using....
namespace MvcMovie.Controllers
{
public class MailController : Controller
{
public ActionResult pageDeTest()
{
MailHelper.SendMail(pageDeTest());
return View();
}
}
}
<div id="demo"></div>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript">
$.getJSON("..\\..\\jsconfig.json", function (data) {
$('#demo').html(JSON.stringify(data));
});
/*console.log("try");*/
</script>

Currently my page MailController.cs had evolve like that:
namespace MvcMovie.Controllers
{
public class MailController : Controller
{
public ActionResult pageDeTest()
{
string myString = RenderPartialViewToString(MailHelper.SendMail());
MailHelper.SendMail(myString);
return View();
}
protected string RenderPartialViewToString(ControllerContext context, string viewName, object model)
{
var controller = context.Controller;
if (string.IsNullOrEmpty(viewName))
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}

Related

Convert MVC View to HTML string - Error " Value does not fall within the expected range."

Following is my Action
public PartialViewResult PrintOrder(string orderNo)
{
ViewBag.OrderId = orderNo;
return PartialView();
}
Following is my code
public static String RenderViewToString(PartialViewResult result,ControllerContext context, String viewPath,string orderNo, object model = null)
{
context.Controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
result.View = ViewEngines.Engines.FindPartialView(context, "PrintOrder").View;
ViewContext vc = new ViewContext(context, result.View, result.ViewData, result.TempData, sw);
result.View.Render(vc, sw);
var html = sw.GetStringBuilder().ToString();
return html;
}
//return "No Data";
}
I am getting an error at result.View.Render(vc, sw) as "Value does not fall within the expected range."
what is the error ?
If required to convert your partial view to html string and return the string from the controller try this code.
Public ActionResult PrintOrder(string orderNo)
{
//code to get the model
this.ViewData.Model = YourModel;
//ViewData["ordno"] = orderNo; uncomment this if you need
var htmlStr = string.Empty;
try {
var sw = new StringWriter();
var viewResult = ViewEngines.Engines.FindPartialView(this.ControllerContext, "partialviewName");
var viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
htmlStr = sw.GetStringBuilder().ToString();
}catch(Exception e){
}
return htmlStr;
}

on a button click I want to pass value to Action method of type HttpGet and then display it on cshtml

on a button click I want to pass value to Action method of type HttpGet and then display it on cshtml
Ex:Controller method
[HttpGet]
public ActionResult GetMandateListForCustomer(int userId, int customerId)
{
var receiptBankUserList = new CustomerMandateReport()
{
GetMandateListForCustomer = _mandateManager.GetMandateListForCustomer(userId, customerId)
};
return View(receiptBankUserList);
}
Here is some example how to do this:
Controller:
[HttpGet]
public string GetMandateListForCustomer(int userId, int customerId)
{
var receiptBankUserList = new CustomerMandateReport()
{
GetMandateListForCustomer = _mandateManager.GetMandateListForCustomer(userId, customerId)
};
return RenderRazorViewToString("ViewName", receiptBankUserList);
}
// use this method to change your view into string
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
}
Method to render view as string is from here
Javascript
$('#btnAddElement').click(function () {
$.get("UrlToAction?userIDd=123&customerId=321", function (data) {
// replace element with class result with
// our new html which we get from controller
$(".result").html(data);
});
});

how to return model from controller to view using jquery?

Code in javascript
function SubmitQuery(Org_UID) {
var ddlProduct_No = $("#Org_UID");
$.ajax({
type: 'POST',
url: '#Url.Action("ShowNewProfessionalWindow", "UpdateOrganizationUID")',
dataType: "html",
data: {
countryno: $("#Org_UID").val() }
My Controller
[HttpPost]
public ActionResult ShowNewProfessionalWindow(string countryno)
{
UpdateOrganizationUIDViewModel model = new UpdateOrganizationUIDViewModel();
//model.Org_UID = OrgUID;
model.org_name_long = "test";
model.org_name_short = "test";
return RedirectToAction("Index", model);
}
How can I return value of model to view using jquery?
Use JsonResult
Change your code and return JsonResult, So use
return Json(model);
instead of
return RedirectToAction("Index", model);
If you want to return View use
First you can create a method as, which will accept ViewName and Model it will return HTML string
public static string RenderRazorViewToString(ControllerContext controllerContext, string viewName, object model)
{
controllerContext.Controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName);
var viewContext = new ViewContext(controllerContext, viewResult.View,
controllerContext.Controller.ViewData, controllerContext.Controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Usage also you have to return JsonResult instead of PartialViewResult
public JsonResult yourpartialviewresult()
{
return Json(new
{
data = RenderRazorViewToString(this.ControllerContext, "partialview", model)
});
}

Merge output of partial view

I have partial view which takes customer object and renders html. For customers list, how to merge output of the partial view on server side like similar to having renderpartial with foreach loop in the view.
//how to write action method for below
foreach(var item in customerslist)
{
//get html by calling the parview
outputhtml += //output from new _partialviewCustomer(item);
}
return outputhtml;
You could render a partial to a string using the following extension method:
public static class HtmlExtensions
{
public static string RenderPartialViewToString(this ControllerContext context, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
{
viewName = context.RouteData.GetRequiredString("action");
}
context.Controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData, context.Controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
}
and then:
foreach(var item in customerslist)
{
//get html by calling the parview
outputhtml += ControllerContext.RenderPartialViewToString("~/Views/SomeController/_Customer.cshtml", item)
}
return outputhtml;

How to Render Partial View into a String

I have the following code:
public ActionResult SomeAction()
{
return new JsonpResult
{
Data = new { Widget = "some partial html for the widget" }
};
}
I'd like to modify it so that I could have
public ActionResult SomeAction()
{
// will render HTML that I can pass to the JSONP result to return.
var partial = RenderPartial(viewModel);
return new JsonpResult
{
Data = new { Widget = partial }
};
}
is this possible? Could somebody explain how?
note, I edited the question before posting the solution.
I opted for an extension method like the following for an ASP.NET MVC 4 app. I think it's simpler than some of the suggestions I've seen:
public static class ViewExtensions
{
public static string RenderToString(this PartialViewResult partialView)
{
var httpContext = HttpContext.Current;
if (httpContext == null)
{
throw new NotSupportedException("An HTTP context is required to render the partial view to a string");
}
var controllerName = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString();
var controller = (ControllerBase)ControllerBuilder.Current.GetControllerFactory().CreateController(httpContext.Request.RequestContext, controllerName);
var controllerContext = new ControllerContext(httpContext.Request.RequestContext, controller);
var view = ViewEngines.Engines.FindPartialView(controllerContext, partialView.ViewName).View;
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
using (var tw = new HtmlTextWriter(sw))
{
view.Render(new ViewContext(controllerContext, view, partialView.ViewData, partialView.TempData, tw), tw);
}
}
return sb.ToString();
}
}
It allows me to do the following:
var html = PartialView("SomeView").RenderToString();
Also, this approach persists any Model, ViewBag and other view data for the view.
This is a slightly modified version of an answer that works:
public static string RenderPartialToString(string controlName, object viewData)
{
ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
viewPage.ViewData = new ViewDataDictionary(viewData);
viewPage.Controls.Add(viewPage.LoadControl(controlName));
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
viewPage.RenderControl(tw);
}
}
return sb.ToString();
}
Usage:
string ret = RenderPartialToString("~/Views/MyController/MyPartial.ascx", model);
DaveDev's answer worked well for me, however when the partial view calls another partial I get "Value cannot be null. Parameter name: view"
Searching around I have made a variant of the following that seems to work well.
public static string RenderPartialToString(string viewName, object model, ControllerContext ControllerContext)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewDataDictionary ViewData = new ViewDataDictionary();
TempDataDictionary TempData = new TempDataDictionary();
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
Usage:
String result = MVCHelpers.RenderPartialToString("PartialViewHere", Model, ControllerContext)
You can create extension that render view into string.
public static class RenderPartialToStringExtensions
{
/// <summary>
/// render PartialView and return string
/// </summary>
/// <param name="context"></param>
/// <param name="partialViewName"></param>
/// <param name="model"></param>
/// <returns></returns>
public static string RenderPartialToString(this ControllerContext context, string partialViewName, object model)
{
return RenderPartialToStringMethod(context, partialViewName, model);
}
/// <summary>
/// render PartialView and return string
/// </summary>
/// <param name="context"></param>
/// <param name="partialViewName"></param>
/// <param name="viewData"></param>
/// <param name="tempData"></param>
/// <returns></returns>
public static string RenderPartialToString(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData)
{
return RenderPartialToStringMethod(context, partialViewName, viewData, tempData);
}
public static string RenderPartialToStringMethod(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData)
{
ViewEngineResult result = ViewEngines.Engines.FindPartialView(context, partialViewName);
if (result.View != null)
{
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter output = new HtmlTextWriter(sw))
{
ViewContext viewContext = new ViewContext(context, result.View, viewData, tempData, output);
result.View.Render(viewContext, output);
}
}
return sb.ToString();
}
return String.Empty;
}
public static string RenderPartialToStringMethod(ControllerContext context, string partialViewName, object model)
{
ViewDataDictionary viewData = new ViewDataDictionary(model);
TempDataDictionary tempData = new TempDataDictionary();
return RenderPartialToStringMethod(context, partialViewName, viewData, tempData);
}
}
And then use it in action
[HttpPost]
public ActionResult GetTreeUnit(string id)
{
int _id = id.ExtractID();
string render = ControllerContext.RenderPartialToString("SomeView");
return Json(new { data = render });
}
Works perfect (Only view name required)
* for parameters you can use a model
* can call this from a view also
View side or Calling Side
BuyOnlineCartMaster ToInvoice1 = new BuyOnlineCartMaster(); // for passing parameters
ToInvoice1.CartID = 1;
string HtmlString = RenderPartialViewToString("PartialInvoiceCustomer", ToInvoice1);
Function Generating HTML
public class BuyOnlineCartMaster
{
public int CartID { get; set; }
}
public static string RenderPartialViewToString(string viewName, object model)
{
using (var sw = new StringWriter())
{
BuyOnlineController controller = new BuyOnlineController(); // instance of the required controller (you can pass this as a argument if needed)
// Create an MVC Controller Context
var wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
RouteData routeData = new RouteData();
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
controller.ViewData.Model = model;
var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.ToString();
}
}
Partial View page
#{
var ModelContents = (Common.BuyOnlineCartMaster)ViewData.Model;
}
Your cart id : #(ModelContents.CartID)
Dave,
a variation on the same theme (mvc v1.0):
protected static string RenderPartialToString(Controller controller, string partialName, object model)
{
var vd = new ViewDataDictionary(controller.ViewData);
var vp = new ViewPage
{
ViewData = vd,
ViewContext = new ViewContext(),
Url = new UrlHelper(controller.ControllerContext.RequestContext)
};
ViewEngineResult result = ViewEngines
.Engines
.FindPartialView(controller.ControllerContext, partialName);
if (result.View == null)
{
throw new InvalidOperationException(
string.Format("The partial view '{0}' could not be found", partialName));
}
var partialPath = ((WebFormView)result.View).ViewPath;
vp.ViewData.Model = model;
Control control = vp.LoadControl(partialPath);
vp.Controls.Add(control);
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
using (var tw = new HtmlTextWriter(sw))
{
vp.RenderControl(tw);
}
}
return sb.ToString();
}
usage within controller:
public string GetLocationHighlites()
{
IBlockData model = WebPagesMapper.GetLocationHighlites();
// **this** being the controoler instance
// LocationPartial.ascx can be defined in shared or in view folder
return RenderPartialToString(**this**,"LocationPartial", model);
}
You can do that out of the box with:
var partial = new HtmlString(Html.Partial("_myPartial", Model).ToString());
public virtual string RenderPartialViewToString(string viewName, object viewmodel)
{
if (string.IsNullOrEmpty(viewName))
{
viewName = this.ControllerContext.RouteData.GetRequiredString("action");
}
ViewData.Model = viewmodel;
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = System.Web.Mvc.ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
var viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
Old post, but I think you are making this too difficult.
Why not return PartialView("<my partial>", model); will return the string you desire.
Just make the Get/Post method an IActionResult as JsonResult, PartialResultand other inherit from ActionResult you can send back anything including a JsonResult
[HttpPost]
public IActionResult CheckForContent(string id, string type){
try{
if(type = "something"){
return Json(new {
success = true,
myProp = "this prop"
});
} else {
MyViewModel model = new MyViewModel();
model.Content = _service.GetContent(new GetContentRequest(){ id = id }
return PartialView("<my partial>", model);
} catch(Exception ex){
_logger.LogError(ex.Message);
return Json(new { success = false }
}
}
Ajax:
$.ajax({
url: '/CheckForContent',
type: 'POST',
cache: false,
contentType: false,
processData: false,
success: function (result) {
if(!result && !result.success){
console.log("Failed to load");
} else if(result && result.success){
$('#MyProp').val(result.myProp);
} else {
$('#MyContainer').html(result);
}
},
});

Resources