Closed badre429 closed 2 years ago
It would be nice if you could decorate a specific method or class with a method to adjust the serializer settings. This would contain it to the specific controller/function and would also be a bit more self documenting in the process.
I didn't originally understand the issue badre429 was describing until I figured out how to get my serializer stuff working. I can see his point now.
Haven't tried in combination with EF yet but I think this would be a workaround:
public class BreezeJsonSettingsAttribute : Attribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
var settings = JsonSerializerSettingsProvider.CreateSerializerSettings();
JsonSerializationFns.UpdateWithDefaults(settings);
context.Result = new JsonResult(((ObjectResult)context.Result).Value, settings);
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
Then decorate method with
[BreezeQueryFilter(Order = 1)]
[BreezeJsonSettings]
The above code by hankor does not work. Any other solutions?
What is the solution here? I want to remove the $type and the $id from some of my controllers that are exposed to third parties and do not want the additional payload of the breeze meta data.
@enkodellc These come from Newtonsoft not Breeze. Typically when using Breeze one replaces the default .NET Core Json Serializer with Newtonsoft, because it's richer for the types of object graphs Breeze endpoints return, and Breeze provides a default configuration that works out of the box, but you can add to it.
The default serializer doesn't handle circularity for example, but you can always use the .NET Core Json serializer for specific controllers and actions. Below is a link to a blog post showing some ways of how you can control the serialization at the action level. Basically you do the serialization yourself in the Action. Either using Newtonsoft with a different configuration from your global config, or using the .NET Core Json serializer in those actions.
https://makolyte.com/aspdotnet-how-to-make-the-controllers-use-newtonsoft/
BTW, for security reasons, you should probably create an entire separate service layer for your public API that you can deploy in a DMZ anyway, and that layer can use its own serialization, different from your internal Breeze service layer.
FYI, I needed this again so I built an attribute extension to handle it.
[ExternalApiJsonReponse] //removes $type and $id from json
[HttpGet]
public async Task<Data> GetData()
{
return data;
}
public class ExternalApiJsonReponseAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
if (context.Result is ObjectResult objectResult)
{
var jsonSerializerSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
PreserveReferencesHandling = PreserveReferencesHandling.None,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameHandling = TypeNameHandling.None,
Formatting = Formatting.Indented,
ContractResolver = new DefaultContractResolver()
};
var json = JsonConvert.SerializeObject(objectResult.Value, jsonSerializerSettings);
context.Result = new ContentResult
{
Content = json,
ContentType = "application/json",
StatusCode = objectResult.StatusCode
};
}
base.OnActionExecuted(context);
}
}
i am using aspnet core over EF6 the breeze api affect all return values my other webapi with $type and $id