MVC:如何将字符串作为 JSON 返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9777731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 18:14:02  来源:igfitidea点击:

MVC: How to Return a String as JSON

asp.net-mvcjson

提问by CodeWarrior

In an effort to make a progress reporting process a little more reliable and decouple it from the request/response, I am performing the processing in a Windows Service and persisting the intended response to a file. When the client starts polling for updates, the intention is that the controller returns the contents of the file, whatever they are, as a JSON string.

为了使进度报告过程更加可靠并将其与请求/响应分离,我正在 Windows 服务中执行处理并将预期的响应持久化到文件中。当客户端开始轮询更新时,目的是控制器以 JSON 字符串形式返回文件的内容,无论它们是什么。

The contents of the file are pre-serialized to JSON. This is to ensure that there is nothing standing in the way of the response. No processing needs to happen (short of reading the file contents into a string and returning it) to get the response.

文件的内容预先序列化为 JSON。这是为了确保没有任何东西阻碍响应。无需进行任何处理(只需将文件内容读入字符串并返回)即可获得响应。

I initially though this would be fairly simple, but it is not turning out to be the case.

我最初虽然这会相当简单,但事实并非如此。

Currently my controller method looks thusly:

目前我的控制器方法看起来如此:

Controller

控制器

Updated

更新

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

And Fiddler is returning this as the raw response

而 Fiddler 将此作为原始响应返回

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

AJAX

Updated

更新

The following will likely be changed later, but for now this was working when I was generating the response class and returning it as JSON like a normal person.

以下内容可能会在以后更改,但目前,当我生成响应类并将其作为 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;
    }
}

回答by Dr. Wily's Apprentice

The issue, I believe, is that the Json action result is intended to take an object (your model) and create an HTTP response with content as the JSON-formatted data from your model object.

我认为,问题在于 Json 操作结果旨在获取一个对象(您的模型)并创建一个 HTTP 响应,其内容为来自您的模型对象的 JSON 格式数据。

What you are passing to the controller's Json method, though, is a JSON-formatted string object, so it is "serializing" the string object to JSON, which is why the content of the HTTP response is surrounded by double-quotes (I'm assuming that is the problem).

但是,您传递给控制器​​的 Json 方法的是一个 JSON 格式的字符串对象,因此它将字符串对象“序列化”为 JSON,这就是 HTTP 响应的内容被双引号包围的原因(我'我假设这是问题)。

I think you can look into using the Content action result as an alternative to the Json action result, since you essentially already have the raw content for the HTTP response available.

我认为您可以考虑使用 Content 操作结果作为 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

Another alternative would be to deserialize the JSON result from the service into an object and then pass that object to the controller's Json method, but the disadvantage there is that you would be de-serializing and then re-serializing the data, which may be unnecessary for your purposes.

另一种选择是将来自服务的 JSON 结果反序列化为一个对象,然后将该对象传递给控制器​​的 Json 方法,但缺点是您将反序列化然后重新序列化数据,这可能是不必要的为您的目的。

回答by Dmitriy Startsev

You just need to return standard ContentResult and set ContentType to "application/json". You can create custom ActionResult for it:

您只需要返回标准 ContentResult 并将 ContentType 设置为“application/json”。您可以为其创建自定义 ActionResult:

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

And then return it's instance:

然后返回它的实例:

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

回答by Ivan Carmenates García

Yeah that's it without no further issues, to avoid raw string json this is it.

是的,就是这样,没有其他问题,为了避免原始字符串 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
        };
    } 

NOTE: please note that method return type of JsonResultis not working for me, since JsonResultand ContentResultboth inherit ActionResultbut there is no relationship between them.

注:请注意,该方法返回类型JsonResult是不是对我来说有效,因为JsonResultContentResult这两种继承ActionResult,但他们之间没有任何关系。

回答by user3652935

Use the following code in your controller:

在控制器中使用以下代码:

return Json(new { success = string }, JsonRequestBehavior.AllowGet);

and in JavaScript:

在 JavaScript 中:

success: function (data) {
    var response = data.success;
    ....
}

回答by Shoter

All answers here provide good and working code. But someone would be dissatisfied that they all use ContentTypeas return type and not JsonResult.

这里的所有答案都提供了良好且有效的代码。但是有人会不满意它们都ContentType用作返回类型而不是JsonResult.

Unfortunately JsonResultis using JavaScriptSerializerwithout option to disable it. The best way to get around this is to inherit JsonResult.

不幸的JsonResult是使用JavaScriptSerializer没有选项来禁用它。解决这个问题的最好方法是继承JsonResult.

I copied most of the code from original JsonResultand created JsonStringResultclass that returns passed string as application/json. Code for this class is below

我从原始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);
            }
        }
    }

Example usage:

用法示例:

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