ASP.NET MVC использовать контроллер или представление вне контекста приложения MVC

Здравствуйте, я создаю небольшую веб-страницу, которая дает нашим пользователям интерфейс для поиска в нашей базе данных.

Этот веб-сайт должен предоставлять 2 функции веб-сервиса: Search (строка searchString) и GetAccountInfoByInitials (инициалы строки).

Я хотел бы использовать для этого свои контроллеры, но не могу понять, как получить html из ViewResult.

Я пробовал следующее, но результат. ToString () дал мне только строку «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;
}

}

person Androme    schedule 13.09.2010    source источник


Ответы (3)


Это ответ на опубликованный мной вопрос, похожий на этот: Есть ли способ обработать представление MVC (файл aspx) из не веб-приложения?

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

Затем для рендеринга файла:

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);
person marq    schedule 22.09.2010

Я делаю это почти таким же образом, но на самом деле использую сам контроллер, чтобы вернуть частичное представление в строку.

Я использую следующий метод расширения в своем базовом контроллере:

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

с последующим возвращением моего частичного представления следующим образом:

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

Надеюсь, это поможет вам разобраться.

person jim tollan    schedule 13.09.2010
comment
Как вы создаете класс Controller в своем веб-сервисе? Я продолжаю получать нулевое исключение на контроллере.ControllerContext - person Androme; 13.09.2010
comment
DoomStone, мой случай на самом деле отличается, так как это общедоступный api, и поэтому фактически выполняется через контроллер, а не через веб-сервис. Я предполагаю, что в этом случае ваше требование немного отличается от моей реализации ... :( - person jim tollan; 13.09.2010
comment
... просто чтобы добавить, этот вопрос SO как бы охватывает мой подход (т.е. использование mvc в качестве службы RESTful, а не использование веб-служб. Конечно, вам могут потребоваться элементы безопасности подхода веб-службы, и в этом случае все ставки отключены. в любом случае - SO Q - ›stackoverflow.com/questions/118931/asp -net-mvc-web-services - person jim tollan; 13.09.2010

Результат просмотра не содержит страницу отдельно. Asp.net MVC использует его вместе с View Engine, настроенным для получения фактической страницы.

Вы столкнетесь с препятствием, если используете механизм просмотра по умолчанию - см. текст ссылки. В основном потому, что движок просмотра asp.net привязан к контексту. Другие механизмы просмотра не вызовут у вас этой проблемы, но если ресурсы, которые вы пытаетесь уменьшить, уже полагаются на механизм просмотра по умолчанию, это не дает цели. Есть и другие способы обойти это, но я не уверен, насколько они удобны для вас.

person eglasius    schedule 13.09.2010