【问题标题】:ASP MVC View Content as JSONASP MVC 以 JSON 格式查看内容
【发布时间】:2009-05-26 00:15:34
【问题描述】:

我有一个 MVC 应用程序,其中包含很多使用 Ajax (jQuery) 调用的控制器操作,并返回更新屏幕的一部分的部分视图内容。但我宁愿返回 JSON 是这样的。

return Json(new { 
    Result = true, 
    Message = "Item has been saved", 
    Content = View("Partial") 
});

HTML 只是 Json 的一个属性。这意味着我需要检索 View 方法呈现的 HTML。有没有简单的方法可以做到这一点,我见过的几个例子很复杂。

编辑:这个问题最初是针对 ASP.NET MVC 1,但如果版本 2 更容易,我想听听答案。

【问题讨论】:

  • 我将标签更改为 asp.net-mvc,以便人们在他们的偏好设置中看到它。
  • 你找到答案了吗?这似乎成为一个很受欢迎的问题。
  • 还没有。我不认为 N​​erdDinner 的答案符合我的要求。
  • 我同意。 Stackoverflow 上还有 2 个非常相似的问题,都没有答案。 stackoverflow.com/questions/756797/…stackoverflow.com/questions/910168/… 我相信一定有办法。想要这样做似乎很明智。
  • 一年过去了,你有什么发现吗?我在这里也遇到了同样的问题..

标签: asp.net-mvc json partial


【解决方案1】:

这就是答案!它与Martin From's 方法略有不同,它似乎有效。如果缺少某些东西,请人们在 cmets 部分贡献任何代码更改。谢谢。

你的控制器这样称呼它:

string HTMLOutput = Utils.RenderPartialToString("~/Views/Setting/IndexMain.ascx", "", items, this.ControllerContext.RequestContext);

将此添加到类中

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

【讨论】:

  • 谢谢。我正在考虑稍微修改一下以使其更好一点,并将发布结果。
  • 期待看到你的想法
【解决方案2】:

NerdDinner 有一些很好的例子。这是 NerdDinner 中的 SearchController,它有一个名为 SearchByLocation 的方法,它返回一个 JsonDinners 列表 (source code 代表 NerdDinner 是知识共享):

namespace NerdDinner.Controllers {

    public class JsonDinner {
        public int      DinnerID    { get; set; }
        public string   Title       { get; set; }
        public double   Latitude    { get; set; }
        public double   Longitude   { get; set; }
        public string   Description { get; set; }
        public int      RSVPCount   { get; set; }
    }

    public class SearchController : Controller {

        IDinnerRepository dinnerRepository;

        //
        // Dependency Injection enabled constructors

        public SearchController()
            : this(new DinnerRepository()) {
        }

        public SearchController(IDinnerRepository repository) {
            dinnerRepository = repository;
        }

        //
        // AJAX: /Search/FindByLocation?longitude=45&latitude=-90

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult SearchByLocation(float latitude, float longitude) {

            var dinners = dinnerRepository.FindByLocation(latitude, longitude);

            var jsonDinners = from dinner in dinners
                              select new JsonDinner {
                                  DinnerID = dinner.DinnerID,
                                  Latitude = dinner.Latitude,
                                  Longitude = dinner.Longitude,
                                  Title = dinner.Title,
                                  Description = dinner.Description,
                                  RSVPCount = dinner.RSVPs.Count
                              };

            return Json(jsonDinners.ToList());
        }
    }
}

【讨论】:

  • 我不确定这是否符合我的要求。它返回一个 Json 项目列表。顺便说一句,罗伯特,在为 St.Kilda 效力时,我从未选择过你作为开发人员。
  • 我想你把我和其他人搞混了。 :)
  • 我是否正确理解(从您的原始代码),当您返回 JsonResult 时,您想随行看看?因为返回一份晚餐而不是一份晚餐清单很容易。
  • 是的,这正是我想要做的。
【解决方案3】:

【讨论】:

    【解决方案4】:

    我正在使用本文中的 HTML Helper:Render partial view to string in ASP.NET MVC。效果很好!

    【讨论】:

      【解决方案5】:

      我花了很长时间试图做同样的事情。我有一个需要扩展的快速解决方案。

      注意:我已经看到了一个问题。所有 cookie 和其他变量都丢失了 :(

      我做了什么:

      1. 创建新的 ActionResult

        public class JsonHtmlViewResult : ViewResult
        {
            public IJsonHtml Data { get; set; }
        
            public override void ExecuteResult(ControllerContext context)
            {
                if (Data == null)
                {
                    Data = new DefaultJsonHtml();
                }
        
                using (StringWriter sw = new StringWriter())
                {
                    HttpRequest request = HttpContext.Current.Request;
                    HttpContext.Current = new HttpContext(request, new HttpResponse(sw));
        
                    base.ExecuteResult(context);
        
                    Data.HtmlContent = sw.ToString();
                }
        
                // Do the serialization stuff.
                HttpResponseBase response = context.HttpContext.Response;
                response.ClearContent();
                response.ContentType = "application/json";
        
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                response.Write(serializer.Serialize(Data));
            }
        }
        
      2. 数据类

        public interface IJsonHtml
        {
            String HtmlContent { get; set; }
        }
        
        public class DefaultJsonHtml : IJsonHtml
        {
            public String HtmlContent { get; set; }
        }
        
      3. 控制器扩展

        public static ActionResult JsonHtmlViewResult(this Controller controller, string viewName, string masterName, object model, IJsonHtml data)
        {
            if (model != null)
            {
                controller.ViewData.Model = model;
            }
        
            return new JsonHtmlViewResult
            {
                Data = data,
                ViewName = viewName,
                MasterName = masterName,
                ViewData = controller.ViewData,
                TempData = controller.TempData
            };
        }
        

      【讨论】:

        【解决方案6】:

        我使用 Razor 找到了一个更新的答案 http://codepaste.net/8xkoj2

        public static string RenderViewToString(string viewPath, object model,ControllerContext context)
        {            
            var viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
            var view = viewEngineResult.View;
        
        
            context.Controller.ViewData.Model = model;
        
            string result = String.Empty;
            using (var sw = new StringWriter())
            {
        
                var ctx = new ViewContext(context, view, 
                                          context.Controller.ViewData, 
                                          context.Controller.TempData, 
                                          sw);
                view.Render(ctx, sw);
        
                result = sw.ToString();
            }
        
            return result;
        }
        

        【讨论】:

          【解决方案7】:

          为什么不只使用静态 html“部分”并从 json 中获取所有动态内容?当页面加载或需要时,您应该能够使用 jquery 加载 html 文件。

          JQuery Ajax 上的这个链接给出了这个例子:

          //Alert out the results from requesting test.php (HTML or XML, depending on what was returned).
          $.get("test.php", function(data){
            alert("Data Loaded: " + data);
          });
          

          【讨论】:

          • 我可以这样做,但 ASP MVC 的工作方式是编写管道代码的工作量更大。
          【解决方案8】:

          克雷格,

          看看这个。 Jeffery Palermo 为 ASP.NET MVC 编写了一个子控制器,它应该可以完成你想要的:

          MvcContrib - 现在支持 ASP.NET MVC 的子控制器: http://jeffreypalermo.com/blog/mvccontrib-now-with-subcontroller-support/

          【讨论】:

          • 如何使用这种方法从 View 返回 HTML 内容?
          【解决方案9】:

          我不知道你从哪个版本号开始可以做到这一点,但现在你可以用一种非常简单的方式返回 JSON:

          public ActionResult JSONaction()
          {
              return Json(data, JsonRequestBehavior);
          }
          

          不需要复杂的助手等。

          数据当然是来自模型的数据 JsonRequestBehavior 指定是否允许来自客户端的 HTTP GET 请求。 (source) 是可选的

          【讨论】:

          • 问题不是返回 Json,而是将视图附加到 Json。
          猜你喜欢
          • 1970-01-01
          • 2020-07-30
          • 2011-02-04
          • 1970-01-01
          • 1970-01-01
          • 2016-06-25
          • 1970-01-01
          • 1970-01-01
          • 2018-03-29
          相关资源
          最近更新 更多