Как получить HTML возвращается из ActionResult в контроллере - PullRequest
2 голосов
/ 10 июля 2009

Я пытаюсь реализовать функцию, аналогичную связанным вопросам в 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);
  }

EDIT:

Я думаю, что мне поможет изучить и реализовать решение моего 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));
        }

Выглядит как папка ' Search ' в папке Views и PartialView с именем ' Title '. A SearchController .cs с использованием следующего метода:

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

Что идет в Titles.ascx для отображения html?

Ответы [ 2 ]

4 голосов
/ 10 июля 2009

Цель JSON () - вернуть объект JSON, а не HTML. Объект JSON будет выглядеть примерно так: {html_value: "

blah"}. Я не уверен, что ожидает ваш запрос ajax. Если он ожидает JSON (у вас дважды установлен dataType), вы можете сделать что-то вроде анонимного объекта:
return Json(new {html_value = retVal});

Однако, если вы хотите вернуть HTML с вашего контроллера - не . Это точно для чего предназначен вид. Создайте представление без какой-либо главной страницы, выполните цикл и верните HTML-код таким образом. Ajax-приложения могут использовать этот HTML-код и удалять его там, где это необходимо.

На самом деле, хотя технически вы могли бы выполнять вышеуказанный анонимный объект (где вы возвращаете html внутри объекта json), это не то, для чего он нужен. Если вы хотите использовать JSON, вы должны возвращать значения и разрешать JavaScript в клиентском формате отформатировать его:

Я не уверен, насколько "тяжел" ваш объект проблем, но предположим, что он имеет только три поля, которые вы используете. В этом случае выполните:

return Json(issues);

EDIT

Ну, я думаю, что "Best Practice" будет возвращать только значения через 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 голос
/ 10 июля 2009

Вы всегда можете вернуть HTML в виде строки. Я не говорю, что это обязательно так, и я согласен с Джеймсом Шенноном в том, что не нужно использовать JSON для возврата HTML.

Фил Хаак написал отличную статью об этом в своем блоге еще в мае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...