Passing json through a controller - json

I have this back-end system that produces json. Is it possible to pass that data through a controller on request and correctly setting the mimetype? Everything I've tried so far tries to re-serialize the data and thus escaping json string.
I've tried adding [Produces("application/json")] to the controller. Setting the response type: Response.ContentType = MediaTypeNames.Application.Json;, returning a JsonResult object: return new JsonResult(jsonString);
The back-end doesn't have a JsonSerializer I can add to the JsonSerializerOptions and I only need it for this specific controller.
In short: If I just return the json string as an IActionResult without doing anything the controller works except for the fact that the content-type isn't set to application/json. Is there any way to do this without affecting anything else?
I feel like this shouldn't be such a exceptional use case but I just can't seem to find the answer.

I had the same need. I solved it by having my action method return an ActionResult like so:
public ActionResult SomeActionMethod(){
string json = GetJsonFromBackenend();
return new ContentResult {
Content = json,
ContentType = "application/json; charset=utf-8",
StatusCode = StatusCodes.Status200OK
};
}
You could declare the return type as an IActionResult if you prefer as #Jurgy mentioned.

Related

I get a null object or an object with null values when passing data from an ajax call to MVC Controller

I will eventually need this method to use an array of keyValue pares so passing in data one attribute per parameter is not going to work for me. I will need a dynamic object. however, I can't get the JSON interpretation to work.
I have a very simple ajax call:
$.ajax({
method:'POST',
url,
success: doAThing
contentType:"application/json;charset=utf-8",
data:JSON.stringfy({thing:'stuff'}), //I have tried just {thing:'stuff'}) as well.
dataType: "json"
})
It goes into a controller:
public class THING
{
public string thing { get; set; }
}
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult SetDAConfigs(THING param) {
//do something
}
I have tried about 50 different configurations. I can either get a null object for "thing" or an object with null values. or a 500 error.
Can anyone tell what is going on? I suspect its an issue with the controller endpoint but I cant figure out what.
So what you need to do is put "param" in your json string.
so instead of handing in data'{"thing":"stuff"}' it should be '{"param":{"thing":"stuff"}}
what will happen is the controller will parse the json associate "param" and try to turn it into the Class associated with the parameter in the controller.

How to force DotNetCore 2.1 Web API to output Json format? What library do I need?

I be straight to the point. I am in the process of converting ASP.Net web services into DotNetCore 2.1 services. My question is very simple. How do I get json output from a string (with a GET verb)?
I'm new at this, but almost every piece of documentation and recommendations do not work with DotNetCore.
Obviously, the following will not work:
[HttpGet]
public string Get()
{
return "{\"country_code\":\"US\",\"country_name\":\"United States\",\"region_name\":\"California\",\"city_name\":\"Los Angeles\",\"latitude\":\"34.052230\",\"longitude\":\" - 118.243680\",\"zip_code\":\"90001\",\"time_zone\":\" - 08:00\"}";
}
I just need to convert this string (or tell the client) that I want the output in json. The following does not work either - got a squiggly line under the "Json(" method and, for the life of me, can't find a reference to make it go away (I pulled it from an example, so they must be using a 3rd party json parsing library or there's a reference that I'm missing)
[HttpGet]
public JsonResult Get()
{
return Json("{\"country_code\":\"US\",\"country_name\":\"United States\",\"region_name\":\"California\",\"city_name\":\"Los Angeles\",\"latitude\":\"34.052230\",\"longitude\":\" - 118.243680\",\"zip_code\":\"90001\",\"time_zone\":\" - 08:00\"}", "application/json");
}
Ideally, I'd like to serialize an object to json, but figured I'd start with something ridiculously simple.
Anywho, if anyone can help.
If you don't already have a strongly typed model, you can build an anonymous type and return that from the controller
Simple Example.
public class MyController: Controller {
[HttpGet]
public IActionResult Get() {
var model = new {
country_code = "US",
country_name = "United States",
region_name = "California",
city_name = "Los Angeles",
latitude = 34.052230,
longitude = -118.243680,
zip_code = 90001,
time_zone = "- 08:00"
};
return Ok(model); //200 OK with content
}
}
In more complex scenarios you would get your objects from a data source.
No library needed, the framework out of the box will serialize the object(s) into JSON for you by default unless otherwise configured.
If you insist on passing a manually formatted string then use the ContemntResult object. Pass it the string and the content type.
[HttpGet]
public IActionResult Get() {
string json = "{\"country_code\":\"US\",\"country_name\":\"United States\",\"region_name\":\"California\",\"city_name\":\"Los Angeles\",\"latitude\":\"34.052230\",\"longitude\":\" - 118.243680\",\"zip_code\":\"90001\",\"time_zone\":\" - 08:00\"}";
return Content(json, new MediaTypeHeaderValue("application/json"));
}
Reference Format response data in ASP.NET Core Web API
Forcing a Particular Format
If you would like to restrict the response formats for a specific action you can apply the
[Produces] filter. The [Produces] filter specifies the response
formats for a specific action (or controller). Like most Filters, this
can be applied at the action, controller, or global scope.
[Produces("application/json")]
public class AuthorsController
The [Produces] filter will force all actions within the
AuthorsController to return JSON-formatted responses, even if other
formatters were configured for the application and the client provided
an Accept header requesting a different, available format.
Don't return string but object. So result of your actions are json string this is why you will get string in JSON and not an object
Make sure that your client is sending header "Content-Type": "application/json".
[HttpGet]
public Address Get()
{
return new Address{ CountryCode = "US"} ;
}

Get json content of request and response on annotated Spring Controller

I want to build a library that will save the Json content of request and response on annotated Spring controller.
So i've build my own annotation #Foo and put it on some controllers:
#Foo
#RequestMapping(method = RequestMethod.POST, value = "/doSomeThing", produces = {
MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE,
MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<T> doSomething(/*some parameters*/) {
T t = doSomeJob(T.class);
return new ResponseEntity<T>(t, HttpStatus.OK);
}
I have no guarantee that request and response are in Contrellor's parameters!
And i'm catching the call on any Controller having that annotation within an #AfterReturning AOP pointcut.
#Component
#Aspect
public class XYInterceptor
#AfterReturning(
pointcut = "execution(#my.annotation.Foo)")
public void doSomethingWithJsonContent(JoinPoint joinPoint) throws Throwable {
//How can i get json value of request and response here?
}
How can I get request and response content formatted in json (such as it is send/returned to the client) ?
Thanx for your help!
Well, you need request and response somehow accessible from your controller method, either via an injected class member, method parameter or method return value. It has got to be somewhere. Because you did not explain where you intend to get it from, I can just post a general answer showing how to determine method arguments and return value from an #AfterReturning advice. If you update the question with more detailed information, I can also update the answer accordingly.
My pointcut (the commented-out one also works, choose your favourite one) binds the return value to a parameter and just assumes that both request and response are of String type. Feel free to replace by your favourite. Furthermore, you can bind a parameter from your intercepted method (no matter where it is in the signature) to a typed advice method parameter if you know that the parameter exists and also know its (super) type. This way you can get rid of the slow and ugly loop over getArgs().
//#AfterReturning(pointcut = "execution(#my.annotation.Foo * *(..))", returning = "response")
#AfterReturning(pointcut = "#annotation(my.annotation.Foo)", returning = "response")
public void interceptRequest(String response, JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof String)
System.out.println(" request = " + arg);
}
System.out.println(" response = " + response);
}

How to get all field of Action class which implement ModelDriven Interface for bean class [duplicate]

I would like to have an Action class which should accept a JSON string constructed from user interface with no setter and getter in the Action class.
Is it possible? If so, what conventions would I need to follow in Action class and in configuration files (struts.xml)?
Post them as content with type "application/json". You may do it with a simple jQuery Ajax call where you could specify the content-type and dataType.
$.ajax({
type: "POST",
url: "/the/action/url",
data : {},
dataType:"JSON",
contentType: "application/json; charset=utf-8"
});
Add json plugin to the project dependencies with json-lib-2.3-jdk15.jar. The plugin supplied with the interceptor json that reads and populates an action from the request.
If you don't want to populate the action then you should not use this interceptor. Instead manually parse the request with this or any other third party library to get the JSONObject class. Or you could rewrite the interceptor and comment that code that is using JSONPopulator class but deserialize the object with JSONUtil class.
Also, you might find this examples useful when manually creating/parsing JSON data.
If you want to send JSON object with multiple key-value pair in it and you want to get these key-values in your action class without creating any setters/getters,
In the Action class decleration, we should implement ServletRequestAware and we should override the setServletRequest() method and set the HttpServletRequest attribute
public class YourClass extends ActionSupport implements ServletRequestAware
private HttpServletRequest request;
#Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
And in our targeted function, we should use above request object to get the parameter (by its name as it is set in the json as the key):
public String fetchData() {
String key1Data = getServletRequest().getParameter("key1");
String key2Data = getServletRequest().getParameter("key2");
return SUCCESS;
}
Where your JSON object should have data something like:
var jsonData = {"key1": "Hello", "key2":"There"};

ASP.NET MVC: Specify value provider on a per-action or per-route basis?

I'm trying to set up an action in ASP.NET MVC 3 to handle the payload of a mercurial webhook request - in this case, generated by Kiln.
The payload is JSON, but unfortunately it is sent as a URL encoded form value with the content type application/x-www-form-urlencoded, because apparently using application/json and sending it unencoded with no parameter name would make it too easy and um... standard.
This means that I can't just use the new JsonValueProviderFactory because it only picks up requests using the standard application/json content type. And of course I can't just kludge the factory to also pick up application/x-www-form-urlencoded requests too, because I need those requests to use the form data value provider everywhere else in my app that's actually receiving form data and not JSON.
So, is there a way I can specify that a ValueProvider or ValueProviderFactory should only be used for a specific action or route?
If you create a specific controller to handle these webhook requests, you can assign your unique ValueProvider when you instantiate your controller.
public class KilnController : Controller
{
public KilnController()
{
this.ValueProvider = MyCustomValueProvider;
}
...
}
This should fulfill your need for a custom ValueProvider for these requests.
Turns out that IValueProvider was not the particular bit of extensibility I was looking for - I just needed to use a quick IModelBinder implementation I found courtesy of James Hughes. It needed a little tweaking to cover pulling something out of the form:
public class JsonFormModelBinder : IModelBinder
{
#region [ ModelBinder Members ]
Object IModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
var jsonStringData = request.Form[bindingContext.ModelName];
if (jsonStringData != null) return JsonConvert.DeserializeObject(jsonStringData, bindingContext.ModelType);
else return null;
}
#endregion
}
And the usage:
[HttpPost]
public ActionResult WebHook([ModelBinder(typeof(JsonFormModelBinder))] WebHookMessage payload)
{
return Content("OK");
}