Just open your csproj project file in notepad and find MvcBuildViews and set value to True.
<MvcBuildViews>true</MvcBuildViews>
Just open your csproj project file in notepad and find MvcBuildViews and set value to True.
<MvcBuildViews>true</MvcBuildViews>
Sometimes a developer needs to render a View as string. Practical scenario would be to create an obvious View and send it via e-mail instead displaying it in browser. Here is a simple way to extract content from a rendered View:
Implement RenderViewToString method
public class HomeController : Controller
{
protected string RenderViewToString(string viewName, object model)
{
string result = null;
var view = ViewEngines.Engines.FindView(this.ControllerContext, viewName, null).View;
if (view != null)
{
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
var viewContext = new ViewContext(this.ControllerContext, view,
new ViewDataDictionary(model), new TempDataDictionary(), writer);
view.Render(viewContext, writer);
writer.Flush();
}
result = sb.ToString();
}
return result;
}
}
Call it in your action method
//Somewhere in HomeController...
public ActionResult Index()
{
//Render a View named 'Email' to string variable named 'content'
//Second parameter (model) can be null
string content = RenderViewToString("Email", new EmailModel());
//Do something with the content, e.g. send it to e-mail
//This does nothing to do with rendered string
return View();
}
Note! This blog post is just an idea than well tested solution, more a review that detailed description.
In Silverlight UserControl and Page classes are usually used with xaml. Root tags in xaml define the type, like so:
xaml
<UserControl x:Class="MyView">
...
</UserControl>
code-behind
namespace MyNamespace
{
class MyView : UserControl
}
Sometimes, developers want to extend UserControl, i.e. as View by MVVM pattern.
xaml
<v:ViewBase x:Class="MyNamespace.MyView" xmlns:v="clr-namespace:MyNamespace">
...
</v:ViewBase>
code-behind
namespace MyNamespace
{
class MyView : ViewBase /* ViewBase is a custom class */
}
Step further, every View should have it’s specialized model (ViewModel), thus base class could integrate a Model property. To avoid casting one should use generics, like ViewBase<MyViewModel>.
xaml
<!-- There's a problem, generics cannot be written in xaml. -->
code-behind
namespace MyNamespace
{
class MyView : ViewBase<MyViewModel> /* ViewBase is a custom class */
}
Generics cannot be written directly in xaml? There is a workaround:
1. Use a wrapper, described here
2. Create a new non-generic class, like in this sample:
xaml
<v:MyViewBase x:Class="MyNamespace.MyView" xmlns:v="clr-namespace:MyNamespace">
...
</v:MyViewBase>
code-behind
namespace MyNamespace
{
class MyView : MyViewBase
}
public abstract class MyViewBase : ViewBase<MyViewModel>
{
/* non-generic class */
}
Appendix: ViewBase<TViewModel> class
public abstract class ViewBase<TViewModel> : UserControl, INotifyPropertyChanged where TViewModel : ViewModelBase, new()
{
private TViewModel model;
public TViewModel Model
{
get
{
if (this.model == null)
{
this.model = new TViewModel();
base.DataContext = this.model;
}
return this.model;
}
set
{
if (this.model != value)
{
this.model = value;
base.DataContext = this.model;
OnPropertyChanged("Model");
}
}
}
}
References: