1

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

}
jim tollan
  • 22,305
  • 4
  • 49
  • 63
Androme
  • 2,399
  • 4
  • 43
  • 82

3 Answers3

0

I do this in almost an identical fashion but actually use the controller iteself to return a partialview to string.

i use the following extension method in my base controller:

public static class ExtensionMethods
{
    public static string RenderPartialToString(this ControllerBase 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();
    }
}

followed by then returning my partialview in the following fashion:

return Content(this.RenderPartialToString("myPartialView", myModel));

This should hopefully sort you out.

jim tollan
  • 22,305
  • 4
  • 49
  • 63
  • How do you create the Controller class in your web service? i keep getting a null exception on controller.ControllerContext – Androme Sep 13 '10 at 12:10
  • DoomStone, my case actually does differ as it's a public api and therefore actually is rolled via the controller, rather than via a webservice. i guees your requirement is slightly different to my implentation in that case... :( – jim tollan Sep 13 '10 at 12:19
  • .. just to add, this SO question kinda covers my approach (i.e. using mvc as a RESTful service, rather than using webservices. of course, you may require the security elements of the webservice approach in which case all bets are off. anyway - SO Q -> http://stackoverflow.com/questions/118931/asp-net-mvc-web-services – jim tollan Sep 13 '10 at 12:22
0

The View Result doesn't holds the page by itself. Asp.net MVC uses it, along with the View Engine configured to get the actual page.

You'll hit a roadblock if you are using the default view engine - see link text. Basically because the asp.net view engine is tied to the context. Other view engines won't give you this issue, but if the assets you are trying to reduce are already relying in the default view engine then that defeats the purpose. There are other ways around it, but I'm unsure how convenient those would be for you.

Community
  • 1
  • 1
eglasius
  • 35,831
  • 5
  • 65
  • 110
0

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);
Community
  • 1
  • 1
marq
  • 808
  • 10
  • 13