Web API:推荐的返回JSON字符串的方法



我有几个服务,这些服务已经接收了一个必须返回客户端的JSON字符串(不是对象)。目前,我正在显式创建HttpResponseMessage,并将其Content属性设置为服务接收的JSON字符串:

var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(jsonUtilizadores, Encoding.UTF8, "application/json");
return response;

现在,使用新的IHttpActionResult有更好的方法吗?使用ContentOk方法最终将JSON字符串用引号包裹,这不是我想要的。

任何反馈?

创建自定义实现。该框架可通过IHttpActionResult扩展。

以下创建自定义结果和扩展方法...

public static class JsonStringResultExtension {
   public static CustomJsonStringResult JsonString(this ApiController controller, string jsonContent, HttpStatusCode statusCode = HttpStatusCode.OK) {
        var result = new CustomJsonStringResult(controller.Request, statusCode, jsonContent);
        return result;
    }
    public class CustomJsonStringResult : IHttpActionResult {
        private string json;
        private HttpStatusCode statusCode;
        private HttpRequestMessage request;
        public CustomJsonStringResult(HttpRequestMessage httpRequestMessage, HttpStatusCode statusCode = HttpStatusCode.OK, string json = "") {
            this.request = httpRequestMessage;
            this.json = json;
            this.statusCode = statusCode;
        }
        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
            return Task.FromResult(Execute());
        }
        private HttpResponseMessage Execute() {
            var response = request.CreateResponse(statusCode);
            response.Content = new StringContent(json, Encoding.UTF8, "application/json");
            return response;
        }
    }
}

...然后可以应用于ApiController派生类。大大简化了以前的电话

return this.JsonString(jsonUtilizadores); //defaults to 200 OK

或带有所需的HTTP状态代码

return this.JsonString(jsonUtilizadores, HttpStatusCode.BadRequest);

将您的Web API设置为返回JSON格式:

    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        // Force to ignore Request Content Type Header and reply only JSON
        config.Formatters.Clear();
        config.Formatters.Add(new JsonMediaTypeFormatter());
        var corsAttr = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(corsAttr);
    }

然后返回响应:

        [HttpGet]
    [Route("{taskId}/list")]
    public IHttpActionResult GetTaskDocuments(string taskId)
    {
        var docs = repository.getTaskDocuments(taskId);
        if (docs != null)
        {
            return Ok(docs);
        }
        else
        {
            return Ok(new ResponseStatus() { Status = Constants.RESPONSE_FAIL, Message = repository.LastErrorMsg });
        }
    }

响应tatus是下一个类:

 public class ResponseStatus
    {
        public string Status { get; set; }
        public string Message { get; set; }
    }

将响应格式留在内容谈判中,以使其符合休息,客户应决定其想要的格式。

在您的Web API操作中,您应该只返回Ok(your object),Web API将看到什么是返回它的最佳格式。

如果您需要省略其他格式,则只需按照Nkosi的建议删除其他MediaTypeFormatter对象。

这是 @nkosi的答案,转换为vb.net。

我正在建立一个WebAPI2后端,以支持Tourofheroes。

我想象我有一个"重"对象的情况,而我不想将所有属性归还所有视图。想象英雄有〜30列,我只需要ID和名称,the Heroes.component.ts ....

我不想创建一个对象来表示每个视图,以便我可以序列化...干燥?

所以,这是@NKOSI发布的两个类。不确定共享类是必要的,我只是像@NKOSI编写的那样实施。

Imports System.Net.Http
Imports System.Web.Http
Imports System.Net
Imports System.Threading
Imports System.Threading.Tasks
Public Class JsonStringResultExtension
    Public Shared Function JSONString(Controller As ApiController,
                                                Optional jsonContent As String = "",
                                             Optional statusCode As HttpStatusCode = HttpStatusCode.OK) As CustomJsonStringResult
        Dim result As New CustomJsonStringResult(Controller.Request, statusCode, jsonContent)
        Return result
        End Function
  End Class
    Public Class CustomJsonStringResult
        Implements IHttpActionResult
    Private json As String
    Private statusCode As HttpStatusCode
    Private request As HttpRequestMessage
    Public Sub New(httpRequestMessage As HttpRequestMessage, Optional statusCode As HttpStatusCode = HttpStatusCode.OK, Optional json As String = "")
        Me.request = httpRequestMessage
        Me.json = json
        Me.statusCode = statusCode
    End Sub
    Public Function ExecuteAsync(cancellationToken As CancellationToken) As Task(Of HttpResponseMessage) Implements IHttpActionResult.ExecuteAsync
        Return Task.FromResult(Execute())
    End Function
    Private Function Execute() As HttpResponseMessage
        Dim response = request.CreateResponse(statusCode)
        response.Content = New StringContent(json, Encoding.UTF8, "application/json")
        Return response
    End Function

End Class

我还会补充说,您必须对Webapiconfig.vb进行以下内容,否则您将收到无法解析HTML

的投诉
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(New MediaTypeHeaderValue("text/html"))
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(New MediaTypeHeaderValue("application/json"))

这是支持heroes.component.js的WebAPI控制器调用就像@luis Abreu一样,我的BOS已经返回JSON。我只想将正确形成的JSON作为字符串返回,而不是将我的BO映射到API中的另一个类中,以实现序列化...

 <HttpGet>
        <Route("")>
        Public Function GetAllHeroes() As CustomJsonStringResult
           'populate a list of heros however you want 
            dim ag as  new  HeroAg()
            Dim l As List(Of TOHbos.Hero) = ag.Items

            'This should be shoved down into a reusable class...ListToJSON
            Dim sb As New StringBuilder("")
            Dim first As Boolean = True
            sb.Append("[")
            For Each h As TOHbos.Hero In l
                If first = True Then
                    first = False
                Else
                    sb.Append(", ")
                End If
                 'decide which fields to include and generate a JSON document
                 h.decideWhichFieldsGetSerializedForThisView()
                sb.Append(h.JSON)
            Next
            sb.Append("]")
            Return JsonStringResultExtension.JSONString(Me, sb.ToString(), HttpStatusCode.OK)
        End Function

我遇到的下一个问题是,我从浏览器控制台的Angular应用中遇到了此错误

 Http failure during parsing for localhost:4300/api/heroes

使用jsonlint.com,我能够弄清楚我的JSON并不完全正确。我并没有将关键名称放在双tick中,而是将值放在一个tick中。虽然这可能是可以接受的JSON,但Jsonlint抱怨,我想Angular RXJS

也是如此

最新更新