簡體   English   中英

同時返回帶有HTML和JavaScript的PartialView

[英]Returning a PartialView with both HTML and JavaScript

我正在進行AJAX調用(使用jQuery)以檢索PartialView 與HTML一起,我想發回View顯示的對象的JSON表示。 我一直使用的糟糕方法是將屬性作為隱藏的輸入嵌入HTML中,這很快變得笨拙並且緊密地耦合了太多的東西。

我可以將HTML后面的<script>標記中的JavaScript發送出去,但是我真的想把這些東西分開。 看起來像這樣:

<%@ Control Language="C#" AutoEventWireup="true" Inherits="System.Web.Mvc.ViewUserControl<Person>" %>
<div class="person">
  First Name: <%= Html.TextBox("FirstName", Model.FirstName) %>
  Last Name: <%= Html.TextBox("LastName", Model.LastName) %>
</div>
<script type="text/javascript">
  // JsonSerialized object goes here
</script>

我考慮過的另一種選擇是對返回JsonResult的動作進行第二次AJAX調用,但這也感覺設計不好。

我想我找到了一個很好的方法,只需將JSON包裝在HtmlHelper擴展中即可。 這是課程:

using System.Web.Script.Serialization;

public static class JsonExtensions {
    public static string Json(this HtmlHelper html, string variableName) {
        return Json(html, variableName, html.ViewData.Model);
    }

    public static string Json(this HtmlHelper html, string variableName, object model) {
        TagBuilder tag = new TagBuilder("script");
        tag.Attributes.Add("type", "text/javascript");
        JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
        tag.InnerHtml = "var " + variableName + " = " + jsonSerializer.Serialize(model) + ";";
        return tag.ToString();
    }
}

您通過以下方式調用它:

<%= Html.Json("foo") %>
<%= Html.Json("bar", Model.Something) %>

我能想到的一個問題是,這不是一個完全完美的分離。 從技術上講,您仍然將JavaScript放入HTML。 但是 ,它不會對服務器進行額外的調用,並且IDE中的標記仍然非常干凈。

可能不是您會得到的最優雅的答案,而只是把它扔在那里:

您可以從操作方法中返回純json,

看起來像這樣的東西:

{
    Html: "<div class=\"person\"> etc...",
    Json: { // your object here
          }
}

在控制器中,您將需要如下所示的視圖:

var existingContext = HttpContext.Current;
var writer = new StringWriter();
var response = new HttpResponse(writer);
var httpContext = new HttpContext(existingContext.Request, response);

var viewResult = myAction(bla);

HttpContext.Current = httpContext;

viewResult.ExecuteResult(this.ControllerContext)

HttpContext.Current = existingContext;
var viewAsHtml = writer.ToString();

與安德魯相同的解決方案,但可能更像是MVC ...

創建一個新類,該類繼承自ViewPage。 重寫其Render方法以呈現頁面本身,然后將其填充到Andrew建議的輸出中。 這樣,所有駭客都會在應發生的Render方法中發生。

現在,您創建的每個視圖都會更改該行:

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<MyModel>" %>

<%@ Page Title="" Language="C#" Inherits="CustomViewPage<MyModel>" %>

我自己沒有檢查它,但是猜測它應該可以工作。 如果您願意,我可以嘗試構建它。

public static string RenderPartialToString(string controlName, object viewData, object model, System.Web.Routing.RequestContext viewContext)
            {

                ViewDataDictionary vd = new ViewDataDictionary(viewData);
                ViewPage vp = new ViewPage { ViewData = vd };

                vp.ViewData = vd;
                vp.ViewData.Model = model;
                vp.ViewContext = new ViewContext();
                vp.Url = new UrlHelper(viewContext);

                Control control = vp.LoadControl(controlName);

                vp.Controls.Add(control);

                StringBuilder sb = new StringBuilder();

                using (StringWriter sw = new StringWriter(sb))
                {

                    using (HtmlTextWriter tw = new HtmlTextWriter(sw))
                    {

                        vp.RenderControl(tw);

                    }

                }

                return sb.ToString();

            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM