MVC: как вернуть строку в виде JSON



чтобы сделать процесс отчетности о ходе выполнения немного более надежным и отделить его от запроса/ответа, я выполняю обработку в службе Windows и сохраняю предполагаемый ответ на файл. Когда клиент начинает опрашивать обновления, предполагается, что контроллер возвращает содержимое файла, какими бы они ни были, в виде строки JSON.



содержимое файла предварительно сериализуется в JSON. Это для того, чтобы ничего не было стоя на пути ответа. Никакая обработка не должна происходить (за исключением чтения содержимого файла в строку и возврата его), чтобы получить ответ.



Я изначально, хотя это было бы довольно просто, но это оказался не тот случай.



В настоящее время мой метод контроллера выглядит так:



контроллер



Обновлено



[HttpPost]
public JsonResult UpdateBatchSearchMembers()
{
string path = Properties.Settings.Default.ResponsePath;
string returntext;
if (!System.IO.File.Exists(path))
returntext = Properties.Settings.Default.EmptyBatchSearchUpdate;
else
returntext = System.IO.File.ReadAllText(path);

return this.Json(returntext);
}


и скрипач возвращает это как сырье ответ



HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 19 Mar 2012 20:30:05 GMT
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 3.0
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 81
Connection: Close

"{"StopPolling":false,"BatchSearchProgressReports":[],"MemberStatuses":[]}"


AJAX



Обновлено



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



this.CheckForUpdate = function () {
var parent = this;

if (this.BatchSearchId != null && WorkflowState.SelectedSearchList != "") {
showAjaxLoader = false;
if (progressPending != true) {
progressPending = true;
$.ajax({
url: WorkflowState.UpdateBatchLink + "?SearchListID=" + WorkflowState.SelectedSearchList,
type: 'POST',
contentType: 'application/json; charset=utf-8',
cache: false,
success: function (data) {
for (var i = 0; i < data.MemberStatuses.length; i++) {
var response = data.MemberStatuses[i];
parent.UpdateCellStatus(response);
}
if (data.StopPolling = true) {
parent.StopPullingForUpdates();
}
showAjaxLoader = true;
}
});
progressPending = false;
}
}
478   4  

4 ответов:

проблема, я считаю, заключается в том, что результат действия Json предназначен для получения объекта (вашей модели) и создания HTTP-ответа с содержимым в виде данных в формате JSON из вашего объекта модели.

то, что вы передаете в метод JSON контроллера, является JSON-форматированным string object, поэтому он" сериализует " строковый объект в JSON, поэтому содержимое HTTP-ответа окружено двойными кавычками (я предполагаю, что это проблема.)

Я думаю, что вы можете изучить использование результата действия содержимого в качестве альтернативы результату действия Json, поскольку у вас уже есть необработанный контент для ответа HTTP.

return this.Content(returntext, "application/json");
// not sure off-hand if you should also specify "charset=utf-8" here, 
//  or if that is done automatically

Другой альтернативой было бы десериализовать результат JSON из службы в объект, а затем передать этот объект в метод JSON контроллера, но недостаток заключается в том, что вы будете де-сериализовать, а затем повторно сериализовать данные, которые могут будьте ненужны для ваших целей.

вам просто нужно вернуть стандартный ContentResult и установить ContentType в "application/json". Вы можете создать пользовательский ActionResult для него:

public class JsonStringResult : ContentResult
{
    public JsonStringResult(string json)
    {
        Content = json;
        ContentType = "application/json";
    }
}

а затем вернуть его экземпляр:

[HttpPost]
public JsonResult UpdateBatchSearchMembers()
{
    string returntext;
    if (!System.IO.File.Exists(path))
        returntext = Properties.Settings.Default.EmptyBatchSearchUpdate;
    else
        returntext = Properties.Settings.Default.ResponsePath;

    return new JsonStringResult(returntext);
}

Да, это без каких-либо дополнительных проблем, чтобы избежать необработанной строки json это он.

    public ActionResult GetJson()
    {
        var json = System.IO.File.ReadAllText(
            Server.MapPath(@"~/App_Data/content.json"));

        return new ContentResult
        {
            Content = json,
            ContentType = "application/json",
            ContentEncoding = Encoding.UTF8
        };
    } 

Примечание: обратите внимание, что метод возвращает тип JsonResult не работает для меня, так как JsonResult и ContentResult как наследовать ActionResult но между ними нет никакой связи.

все ответы здесь дают хороший и рабочий код. Но кто-то будет недоволен, что они все используют ContentType как тип возврата, а не JsonResult.

к сожалению JsonResult использует JavaScriptSerializer без возможности отключить его. Лучший способ обойти это-наследовать JsonResult.

Я скопировал большую часть кода из оригинала JsonResult и создал JsonStringResult класс, который возвращает переданную строку как application/json. Код для этого класса ниже

public class JsonStringResult : JsonResult
    {
        public JsonStringResult(string data)
        {
            JsonRequestBehavior = JsonRequestBehavior.DenyGet;
            Data = data;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
                String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException("Get request is not allowed!");
            }

            HttpResponseBase response = context.HttpContext.Response;

            if (!String.IsNullOrEmpty(ContentType))
            {
                response.ContentType = ContentType;
            }
            else
            {
                response.ContentType = "application/json";
            }
            if (ContentEncoding != null)
            {
                response.ContentEncoding = ContentEncoding;
            }
            if (Data != null)
            {
                response.Write(Data);
            }
        }
    }

пример использования:

var json = JsonConvert.SerializeObject(data);
return new JsonStringResult(json);

Comments

    Ничего не найдено.