Solving development problems  |  About this blog

Archive for the ‘view’ tag

How to show compiler errors in ASP.NET MVC Views?

Just open your csproj project file in notepad and find MvcBuildViews and set value to True.

<MvcBuildViews>true</MvcBuildViews>

Written by Avivo

February 7th, 2011 at 4:21 pm

ASP .NET MVC: How to render View into a string

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();
}

Written by developer

March 31st, 2010 at 10:38 pm

Silverlight: inherit a generic class from UserControl

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:

Written by developer

November 30th, 2009 at 6:57 pm