Search code examples
asp.net-mvcweb-servicesviewengine

ASP.NET MVC Use Controller or View outside of the MVC application context


Hello i am creating a small webpage that give our users an interface to search in our database.

This website must supply 2 webservice functions, Search(string searchString) and GetAccountInfoByInitials(string initials)

I would like to use my controllers to do this, but i can not find out how i can get the html out of a ViewResult.

I have tryed the following, but the result.ToString() only give me the string "System.Web.Mvc.ViewResult"

public class SearchService : ISearchService

{

private readonly ServiceHandlerController _controller;
public SearchService()
{
    _controller = new ServiceHandlerController();
}

public string Search(string searchString)
{
    var result = _controller.Search(searchString);
    return result.ToString();
}

public string GetAccountInfoByInitials(string initials)
{
    var result = _controller.Search(initials).ToString();
    return result;
}

}

Solution

  • This is an answer to a question I posted similar to this one: Is there a way to process an MVC view (aspx file) from a non-web application?

    public class AspHost : MarshalByRefObject
    {
        public string _VirtualDir;
        public string _PhysicalDir;
    
        public string ViewToString<T>(string aspx, Dictionary<string, object> viewData, T model)
        {
            StringBuilder sb = new StringBuilder();
            using (StringWriter sw = new StringWriter(sb))
            {
                using (HtmlTextWriter tw = new HtmlTextWriter(sw))
                {
                    var workerRequest = new SimpleWorkerRequest(aspx, "", tw);
                    HttpContext.Current = new HttpContext(workerRequest);
    
                    ViewDataDictionary<T> viewDataDictionary = new ViewDataDictionary<T>(model);
                    foreach (KeyValuePair<string, object> pair in viewData)
                    {
                        viewDataDictionary.Add(pair.Key, pair.Value);
                    }
    
                    object view = BuildManager.CreateInstanceFromVirtualPath(aspx, typeof(object));
    
                    ViewPage viewPage = view as ViewPage;
                    if (viewPage != null)
                    {
                        viewPage.ViewData = viewDataDictionary;
                    }
                    else
                    {
                        ViewUserControl viewUserControl = view as ViewUserControl;
                        if (viewUserControl != null)
                        {
                            viewPage = new ViewPage();
                            viewPage.Controls.Add(viewUserControl);
                        }
                    }
    
                    if (viewPage != null)
                    {
                        HttpContext.Current.Server.Execute(viewPage, tw, true);
    
                        return sb.ToString();
                    }
    
                    throw new InvalidOperationException();
                }
            }
        }
    
        public static AspHost SetupFakeHttpContext(string physicalDir, string virtualDir)
        {
            return (AspHost)ApplicationHost.CreateApplicationHost(
                typeof(AspHost), virtualDir, physicalDir);
        }
    }
    

    Then, to render a file:

    var host = AspHost.SetupFakeHttpContext("Path/To/Your/MvcApplication", "/");
    var viewData = new ViewDataDictionary<SomeModelType>(){ Model = myModel };
    String rendered = host.ViewToString("~/Views/MyView.aspx", new Dictionary<string, object>(viewData), viewData.Model);