如何从Controller中的ActionResult返回html

时间:2009-07-09 22:04:18

标签: asp.net-mvc ajax json

我正在尝试实现类似于StackOverflow上的相关问题的功能,我在MVC中这样做。

$().ready(function() {
   var s = $("#Summary").val();
   $("#Summary").blur(function() { QuestionSuggestions(s); });
});

function GetPastIssues(title) {

$(document).ready(function() {
$.ajax({ type: "POST",
    url: "/Issue/GetSimilarIssues",
    contentType: "application/json; charset=utf-8",
    dataType: "xml",
    dataType: "json",
    data: "{'title':'" + title + "'}",
    processData: false,
    error: function(XMLHttpRequest, textStatus, errorThrown) { ajaxError(XMLHttpRequest, textStatus, errorThrown); },
    success: function(xml) { ajaxFinish(xml); }
  });
});

function ajaxFinish(xml) {
 if (xml.d != "NO DATA") {
    $('#question-suggestions').html(xml.d); //alert(xml.d); // This ALERT IS returning undefined
    $('#question-suggestions').show();
 }
}

从我的控制器返回的数据是“未定义的”,如ajaxFinish中的注释行所示。
我做错了什么?

//[AcceptVerbs(HttpVerbs.Get)]
[JsonParamFilter(Param = "title", TargetType = typeof(string))]
public ActionResult GetSimilarIssues(string title)
{
    var issues = _db.GetSimilarIssues(title).ToList();
    if (title == null || issues.Count() == 0)
       return Json("NO DATA");

    string retVal = null;
    foreach (Issue issue in _db.GetSimilarIssues(title))
    {
        retVal += "<div class='answer-summary' style='width: 610px;'>";
        retVal += "<a href='Issue.aspx?projid=" + issue.ProjectId.ToString() + "&issuetypeid=" + issue.IssueTypeId.ToString() +
                "&issueid=" + issue.IssueId.ToString() + "'>";
        retVal += issue.Summary;
        retVal += "</a>";
        retVal += "</div>";
    }
        return Json(retVal);
  }

编辑:

我认为什么能帮助我学习和实现我的senario解决方案,如果我能深入了解StackOverflow如何实现这个javascript方法:

function QuestionSuggestions() {
        var s = $("#title").val();            
        if (s.length > 2) {
            document.title = s + " - Stack Overflow";
            $("#question-suggestions").load("/search/titles?like=" + escape(s));
        }

看起来像Views文件夹中的“搜索”文件夹和名为“标题”的 PartialView 。使用以下方法的 SearchController .cs:

public ActionResult titles(string like)
{
   // HOW TO IMPLEMENT THIS
   return PartialView("Titles");
}

Titles.ascx中显示html的内容是什么?

2 个答案:

答案 0 :(得分:4)

JSON()的目的是返回一个JSON对象 - 而不是HTML。 JSON对象就像{html_value:“&lt; li&gt; blah”}。我不确定你的ajax请求是什么。如果它期望JSON(你有两次设置dataType),那么你可以做一些像匿名对象的事情:

return Json(new {html_value = retVal});

但是,如果您想从控制器返回 HTML - 请不要。那是完全视图的用途。创建一个没有任何母版页的视图,然后执行循环并以这种方式返回HTML。 Ajax应用程序可以使用此HTML并在必要时将其删除。

事实上,虽然你在技术上可以做上面的匿名对象(你在json对象里面返回html),但这不是它的用途。如果你想使用JSON,你应该返回值,并让客户端上的javascript格式化它:

我不确定你的问题对象有多“重”,但是假设它只有你正在使用的三个字段。在这种情况下,请执行:

return Json(issues);

修改

嗯,我认为“最佳实践”是通过JSON和javascript中的格式返回值。我对JSON()不够熟悉,但我知道它有效(我将它用于简单的事情)。尝试使用这三个值和

创建一个简单的问题对象
return Json(issuesTxfr);

当您从控制器呼叫时,您不需要使用偏见视图。只需将其视为一个非常简单的视图。这是我的一个例子(请注意我没有遵循我自己的JSON建议 - 这是一段时间后我现在因为一些原因而畏缩看着它):

    public ActionResult Controls_Search_Ajax(string q, string el)
    {
        ...

        ViewData["controls"] = controls;
        ViewData["el"] = el;

        return View();
    }

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Controls_Search_Ajax.aspx.cs" Inherits="IRSoxCompliance.Views.Edit.Controls_Search_Ajax" %>
<% var controls = ViewData.Get<IEnumerable<IRSoxCompliance.Models.Control>>("controls");
   var el = ViewData.Get<String>("el");

   if (controls != null)
   {
     foreach (var c in controls)
     {
%><%= c.Control_ID %>***<%= c.Full_Control_Name %>***<li id="<%= el %>:li:<%= c.Control_ID %>"><span class="item"><%= Html.BreadCrumb(c, false) %></span><span class="actions"><a href="#" onclick="sx_Remove_Control('<%= el %>', <%= c.Control_ID %>); return false;">Remove</a></span><br></li>
<%   }
   }
%>

请注意,没有指定母版页。

答案 1 :(得分:1)

您始终可以将HTML作为字符串返回。我不是说这一定是要走的路,我同意James Shannon关于不使用JSON来返回HTML。

菲尔·哈克(Phil Haack)在5月份的博客上写了一篇很好的article