Newtonsoft JSON 可选地更改负载大小写 WebAPI 2
Newtonsoft JSON optionally change payload casing WebAPI 2
我将驼峰式大小写配置为 Newtonsoft 库的默认 JSON 输出。在 Application_Start 期间调用以下行:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
对 WebAPI 的所有 javascript REST 调用(使用 WebAPI 2)工作正常,return 驼峰 JSON 字符串到客户端。
现在,我在我的一个网页上使用 jTable 控件 (http://www.jtable.org),此控件要求 JSON 有效载荷 returned in Proper案例。 所以问题是 即使默认配置通过 Application_Start 在不更改全局默认设置的情况下设置为驼峰式大小写? 我需要正确的大小写 JSON 有效负载 return 只为应用程序中的这个 WebAPI 调用编辑。
我试过 [http://fizzylogic.nl/2014/07/30/changing-the-casing-of-json-properties-in-asp-dot-net-web-api/] 这个,但我无法让 ActionFilterAttribute.OnActionExecuting 开火。所以解决方案没有奏效。
我还在WebAPI方法中添加了下面这行代码
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new JsonContractResolver(new JsonMediaTypeFormatter());
这可行,但正确大小写现在成为其他 WebAPI 调用的默认格式。
这是 WebAPI 片段
public JTableDtoImpl Get(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "") {
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new JsonContractResolver(new JsonMediaTypeFormatter());
return dto;
}
这里的问题是我现在无法恢复为默认的驼峰式大小写格式,因为那时该方法已经 return 编辑了。
还有其他建议吗?
您需要显式序列化您的 JSON,而不是返回一个对象并让 WebApi 为您序列化它。尝试类似的东西:
public JSonResult Get(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "")
{
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
return Json(dto, JsonRequestBehavior.AllowGet); // This serializes explicitly, before WebApi invokes the default serializer
}
您可以使用 the overload that takes a MediaTypeFormatter 调用 Request.CreateResponse
并传入 new JsonMediaTypeFormatter()
,这与您在全局设置它的方式类似,但专门用于此方法。当然,您可以指定任何您想要的 SerializerSettings
。最好在您的控制器中保留它的私有静态实例,这样您就不会 new
每次都启动它。
这是我的最终 WebAPI 方法,它可以按我需要的方式工作。很遗憾我无法通过 Newtonsoft.Json 库获得此功能,因此该方法将返回业务对象而不是响应对象。为了清楚起见,我从 class 中删除了代码。 (即:跟踪、评论等)。
public class MobileOrdersController : ApiController {
private static readonly MobileOrdersService _svc = new MobileOrdersService();
private static readonly MediaTypeFormatter _properCaseFormatter = new JsonMediaTypeFormatter{
SerializerSettings = new JsonSerializerSettings {
ContractResolver = new DefaultContractResolver()
}
};
[Authorize][HttpGet]
public HttpResponseMessage GetCustomerMobileOrders(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "") {
try {
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
return Request.CreateResponse(HttpStatusCode.OK, dto, _properCaseFormatter);
} catch (Exception ex) {
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}
以下是我使用 WebAPI 2 时大卫推荐的 OkNegotiatedContentResult<> 解决方案。
public class MobileOrdersController : ApiController {
private static readonly MobileOrdersService _svc = new MobileOrdersService();
private static readonly IContentNegotiator _conneg = GlobalConfiguration.Configuration.Services.GetContentNegotiator();
private static readonly IEnumerable<JsonMediaTypeFormatter> _mediaTypeFormatters = new[] {
new JsonMediaTypeFormatter {
SerializerSettings = new JsonSerializerSettings {
ContractResolver = new DefaultContractResolver()
}
}
};
[Authorize][HttpGet]
public IHttpActionResult GetCustomerMobileOrders(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "") {
try {
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
return new OkNegotiatedContentResult<JTableDtoMobileOrdersImpl>(dto, _conneg, Request, _mediaTypeFormatters);
} catch (Exception ex) {
return new ExceptionResult(ex, this);
}
}
}
我将驼峰式大小写配置为 Newtonsoft 库的默认 JSON 输出。在 Application_Start 期间调用以下行:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
对 WebAPI 的所有 javascript REST 调用(使用 WebAPI 2)工作正常,return 驼峰 JSON 字符串到客户端。
现在,我在我的一个网页上使用 jTable 控件 (http://www.jtable.org),此控件要求 JSON 有效载荷 returned in Proper案例。 所以问题是 即使默认配置通过 Application_Start 在不更改全局默认设置的情况下设置为驼峰式大小写? 我需要正确的大小写 JSON 有效负载 return 只为应用程序中的这个 WebAPI 调用编辑。
我试过 [http://fizzylogic.nl/2014/07/30/changing-the-casing-of-json-properties-in-asp-dot-net-web-api/] 这个,但我无法让 ActionFilterAttribute.OnActionExecuting 开火。所以解决方案没有奏效。
我还在WebAPI方法中添加了下面这行代码
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new JsonContractResolver(new JsonMediaTypeFormatter());
这可行,但正确大小写现在成为其他 WebAPI 调用的默认格式。
这是 WebAPI 片段
public JTableDtoImpl Get(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "") {
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new JsonContractResolver(new JsonMediaTypeFormatter());
return dto;
}
这里的问题是我现在无法恢复为默认的驼峰式大小写格式,因为那时该方法已经 return 编辑了。
还有其他建议吗?
您需要显式序列化您的 JSON,而不是返回一个对象并让 WebApi 为您序列化它。尝试类似的东西:
public JSonResult Get(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "")
{
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
return Json(dto, JsonRequestBehavior.AllowGet); // This serializes explicitly, before WebApi invokes the default serializer
}
您可以使用 the overload that takes a MediaTypeFormatter 调用 Request.CreateResponse
并传入 new JsonMediaTypeFormatter()
,这与您在全局设置它的方式类似,但专门用于此方法。当然,您可以指定任何您想要的 SerializerSettings
。最好在您的控制器中保留它的私有静态实例,这样您就不会 new
每次都启动它。
这是我的最终 WebAPI 方法,它可以按我需要的方式工作。很遗憾我无法通过 Newtonsoft.Json 库获得此功能,因此该方法将返回业务对象而不是响应对象。为了清楚起见,我从 class 中删除了代码。 (即:跟踪、评论等)。
public class MobileOrdersController : ApiController {
private static readonly MobileOrdersService _svc = new MobileOrdersService();
private static readonly MediaTypeFormatter _properCaseFormatter = new JsonMediaTypeFormatter{
SerializerSettings = new JsonSerializerSettings {
ContractResolver = new DefaultContractResolver()
}
};
[Authorize][HttpGet]
public HttpResponseMessage GetCustomerMobileOrders(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "") {
try {
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
return Request.CreateResponse(HttpStatusCode.OK, dto, _properCaseFormatter);
} catch (Exception ex) {
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}
以下是我使用 WebAPI 2 时大卫推荐的 OkNegotiatedContentResult<> 解决方案。
public class MobileOrdersController : ApiController {
private static readonly MobileOrdersService _svc = new MobileOrdersService();
private static readonly IContentNegotiator _conneg = GlobalConfiguration.Configuration.Services.GetContentNegotiator();
private static readonly IEnumerable<JsonMediaTypeFormatter> _mediaTypeFormatters = new[] {
new JsonMediaTypeFormatter {
SerializerSettings = new JsonSerializerSettings {
ContractResolver = new DefaultContractResolver()
}
}
};
[Authorize][HttpGet]
public IHttpActionResult GetCustomerMobileOrders(int id, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = "") {
try {
List<MobileOrderModel> orders = _svc.GetMobileOrders(id);
var dto = new JTableDtoMobileOrdersImpl(orders, jtStartIndex, jtPageSize) {
Message = string.Format("DataSource:{0}", _svc.DataSource)
};
return new OkNegotiatedContentResult<JTableDtoMobileOrdersImpl>(dto, _conneg, Request, _mediaTypeFormatters);
} catch (Exception ex) {
return new ExceptionResult(ex, this);
}
}
}