28

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

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

4

10 回答 10

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); 
于 2009-06-27T12:57:23.223 回答
8

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

此外,我还为 MVC Beta 编写了一个类似 Rails 的 RJS javascript 生成框架。

在http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc查看它,让我知道你的想法。

于 2008-11-16T23:26:03.183 回答
7

你会像这样创建你的动作:

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

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

您的 jquery 可能看起来像这样:

$('#targetdiv').load('/MyController/LoginForm',function(){alert('complete!');});
于 2008-11-13T06:36:32.387 回答
5

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

另一种方法是使用 jquery 来调用一些控制器/动作,但 json 使用常规视图(aspx 或 ascx,webforms 视图引擎)来呈现内容,并且使用 jquery 只需将该 html 注入某个 div。这是从 asp.net ajax 到 UpdatePanels 的一半...

我可能会使用第一种方法,使用 json,在那里你几乎没有什么工作要做,但它更加“优化”,因为你不会通过网络传输整个 html,只有序列化的对象。这是“大人物”(gmail、g docs、hotmail、..)这样做的方式——大量使用 UI 操作的 JS 代码。

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

  • html.renderpartial("ascx 的名称")
  • html.RenderAction(x=>x.ActionName) 来自 Microsoft.web.mvc(mvc 期货)
于 2008-11-13T09:32:02.297 回答
4

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

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

于 2008-11-13T05:16:27.367 回答
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。

抱歉得赶我回家的车。如果您想让我详细说明,请告诉我。

于 2010-07-21T05:01:03.663 回答
2

你有几个选择。

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

<% 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,
   });
 %>
于 2008-11-17T01:16:17.407 回答
0

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

于 2008-11-13T03:27:38.147 回答
0

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

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(){ }
 });    
于 2013-01-11T18:22:53.407 回答
0

我发现这一行代码可以完美运行。orderModel 是我的模型对象。就我而言,我有一个辅助方法,我必须在其中合并部分视图的 html。

System.Web.Mvc.Html.PartialExtensions.Partial(html, "~/Views/Orders/OrdersPartialView.cshtml", orderModel).ToString();
于 2017-08-08T17:50:24.253 回答