从控制器内部获取部分视图的HTML

时间:2008-11-13 02:53:55

标签: html asp.net-mvc viewusercontrol

我为我的mvc网站开发了一个简单的机制,通过jquery引入html,然后填充指定的div。一切都很好,看起来很酷 我的问题是我现在正在我的控制器内部创建html标记(这在VB.net中很容易做到btw)我宁可不要混淆一些关注点。

是否可以使用自定义的“MVC View用户控件”来满足这种需求?我可以创建控件的实例,传入模型数据并渲染为html吗?然后,这将是一个简单的渲染和传递回调用浏览器的问题。

10 个答案:

答案 0 :(得分:29)

这是一个与ASP.Net MVC 1.0一起使用的解决方案(许多声称与beta 3一起使用的解决方案不能与1.0一起工作),不会遭受'服务器无法设置HTTP标头后的内容类型发送'问题,可以在控制器内调用(不仅仅是视图):

/// <summary>
/// Render a view into a string. It's a hack, it may fail badly.
/// </summary>
/// <param name="name">Name of the view, that is, its path.</param>
/// <param name="data">Data to pass to the view, a model or something like that.</param>
/// <returns>A string with the (HTML of) view.</returns>
public static string RenderPartialToString(string controlName, object viewData) {
    ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
    viewPage.Url = GetBogusUrlHelper();

    viewPage.ViewData = new ViewDataDictionary(viewData);
    viewPage.Controls.Add(viewPage.LoadControl(controlName));

    StringBuilder sb = new StringBuilder();
    using (StringWriter sw = new StringWriter(sb)) {
        using (HtmlTextWriter tw = new HtmlTextWriter(sw)) {
            viewPage.RenderControl(tw);
        }
    }

    return sb.ToString();
}

public static UrlHelper GetBogusUrlHelper() {
  var httpContext = HttpContext.Current;

  if (httpContext == null) {
    var request = new HttpRequest("/", Config.Url.ToString(), "");
    var response = new HttpResponse(new StringWriter());
    httpContext = new HttpContext(request, response);
  }

  var httpContextBase = new HttpContextWrapper(httpContext);
  var routeData = new RouteData();
  var requestContext = new RequestContext(httpContextBase, routeData);

  return new UrlHelper(requestContext);
}

这是一种静态方法,你可以放在一个方便的地方。你可以这样称呼它:

string view = RenderPartialToString("~/Views/Controller/AView.ascx", someModelObject); 

答案 1 :(得分:8)

我整理了一个粗略的框架,允许您从MVC Beta中的控制器方法向字符串渲染视图。这应该有助于解决这个限制。

此外,我还为MVC Beta制作了类似Rails的RJS javascript生成框架。

http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc查看,告诉我您的想法。

答案 2 :(得分:7)

你可以像这样创建你的行动:

        public PartialViewResult LoginForm()
        {
            var model = // get model data from somewhere
            return PartialView(model);
        }

该操作会将呈现的部分视图返回给您的jquery响应。

你的jquery看起来像这样:

$('#targetdiv').load('/MyController/LoginForm',function(){alert('complete!');});

答案 3 :(得分:5)

您应该使用jquery来填充div(如果需要,还可以创建新的html元素),以及ActionResult的Json序列化。

其他方式是使用jquery来调用一些控制器/动作,但是json使用常规View(aspx或ascx,webforms视图引擎)来渲染内容,而jquery只是将html注入某个div。这是来自asp.net ajax的UpdatePanels的一半...

我可能会选择第一种方法,使用json,你可以做更多的工作,但它更加“优化”,因为你没有通过网络传输整个html,只有序列化的对象。这就是“大人物”(gmail,g docs,hotmail,..)这样做的方式 - 许多用UI操作的JS代码。

如果你不需要ajax,那么你基本上有两种方法来调用部分视图:

  • html.renderpartial(“ascx名称”)
  • 来自Microsoft.web.mvc的
  • html.RenderAction(x =&gt; x.ActionName)(mvc期货)

答案 4 :(得分:4)

经过谷歌的大量挖掘,我找到了答案。 您无法轻松访问视图输出的html。

http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx

答案 5 :(得分:3)

我为我正在开发的应用做了类似的事情。我有部分视图返回渲染内容可以使用他们的REST路径或使用:

调用
<% Html.RenderAction("Action", "Controller"); %>

然后在我的实际显示HTML中,我有一个从jQuery填充的DIV:

<div class="onload">/controller/action</div>

jQuery看起来像这样:

<script type="text/javascript">
    $.ajaxSetup({ cache: false });

    $(document).ready(function () {
        $('div.onload').each(function () {
            var source = $(this).html();
            if (source != "") {
                $(this).load(source);
            }
        });
    });
</script>

这将扫描与“onload”类匹配的所有DIV,并从其内容中读取REST路径。然后它在该REST路径上执行jQuery.load并使用结果填充DIV。

抱歉我要赶回家。如果您希望我详细说明,请告诉我。

答案 6 :(得分:2)

您有几种选择。

在控制器中为视图创建MVC View用户控件和操作处理程序。要渲染视图,请使用

<% Html.RenderPartial("MyControl") %>

在这种情况下,您的操作处理程序需要将模型数据传递给视图

public ActionResult MyControl ()
{
    // get modelData

    render View (modelData);
}

您的另一个选择是从父页面传递模型数据。在这种情况下,您不需要动作处理程序,并且模型类型与父代相同:

<% Html.RenderPartial("MyControl", ViewData.Model) %>

如果您的用户控件具有自己的数据类型,您也可以在页面

中构建它

在MyControl.ascx.cs中:

public class MyControlViewData
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public partial class MyControl : System.Web.Mvc.ViewUserControl <MyControlViewData>
{
}

在您的页面中,您可以初始化控件的数据模型:

<% Html.RenderPartial("MyControl", new MyControlViewData ()
   {
        Name= ViewData.Model.FirstName,
        Email = ViewData.Model.Email,
   });
 %>

答案 7 :(得分:0)

在rails中,这称为渲染局部视图,而您使用render :partial => 'yourfilename'执行此操作。我相信ASP.NET MVC有一个类似的RenderPartial方法,但我找不到MVC的官方文档来确认或否认这样的事情。

答案 8 :(得分:0)

非常简单,您只需创建一个强类型的局部视图(或用户控件),然后在您的cotroller中创建如下:

public PartialViewResult yourpartialviewresult()
{
    var yourModel
    return PartialView("yourPartialView", yourModel);
}

然后您可以使用JQuery随时执行请求:

$.ajax({
    type: 'GET',
    url: '/home/yourpartialviewresult',
    dataType: 'html', //be sure to use html dataType
    contentType: 'application/json; charset=utf-8',
    success: function(data){
         $(container).html(data);
    },
    complete: function(){ }
 });    

答案 9 :(得分:0)

我发现这一行代码完美无缺。 orderModel是我的模型对象。在我的情况下,我有一个帮助方法,我必须合并部分视图的HTML。

System.Web.Mvc.Html.PartialExtensions.Partial(html, "~/Views/Orders/OrdersPartialView.cshtml", orderModel).ToString();