我有几个服务已经收到必须返回给客户端的json字符串(不是对象)。目前,我正在显式创建HttpResponseMessage
并将其Content
属性设置为服务接收的json字符串:
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(jsonUtilizadores, Encoding.UTF8, "application/json");
return response;
现在,使用新的IHttpActionResult
有更好的方法吗?使用Content
或Ok
方法最终用引号包装json字符串,这不是我想要的。
有任何反馈吗?
答案 0 :(得分:10)
创建自定义实现。该框架可通过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);
答案 1 :(得分:4)
将您的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 });
}
}
ResponseStatus是下一个类:
public class ResponseStatus
{
public string Status { get; set; }
public string Message { get; set; }
}
答案 2 :(得分:3)
将响应格式保留给内容协商以符合REST,客户端应该决定它想要的格式。
在您的网址API操作中,您应该返回Ok(your object)
,网址API会看到返回它的最佳格式。
如果您需要省略其他格式化程序,那么就像Nkosi建议的那样删除其他MediaTypeFormatter
个对象。
答案 3 :(得分:1)
这是@Nkosi的回答翻译为VB.Net。
我正在构建WebAPI2后端以支持TourOfHeroes。
我想像一下我有一个“重”对象并且我不想将所有属性返回到所有视图的情况。想象一下Hero有大约30列,而Heroes.component.ts ....我只需要ID和名称。
我不想另外创建一个对象来代表每个视图,以便我可以对它们进行JSON序列化...干吗?
因此,这是@NKosi发布的2个类。不确定共享类是否必要,我只是按照@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一样,我的BO已经返回了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不太正确。我不是将键名放在双打勾中,而是将值放在单打勾中。尽管这可能是可接受的JSON,但是jsonLint抱怨,我想Angular rxjs也是如此