Option 1:
If I deserialize my JSON request manually, I get a correct result:
[Route("search")]
[HttpPost]
public IEnumerable<ErrorLogDto> Search(HttpRequestMessage request)
{
string res = request.Content.ReadAsStringAsync().Result;
LogSearchDto dto = JsonConvert.DeserializeObject(res, typeof(LogSearchDto)) as LogSearchDto;
//dto = not null
Option 2: If I use this, I always get NULL value for dto:
[Route("search")]
[HttpPost]
public IEnumerable<ErrorLogDto> Search([FromBody]LogSearchDto dto)
{
// dto = null!
I am out of ideas how to debug this..
After a long search, I solved the problem by removing following lines from Global.asax.cs:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.UseDataContractJsonSerializer = true;
Related
I have ApiController which receives a specific object of a class. That works perfect but what if, HTTP Request which contains a body with JSON is not matching with the object of a class? I will receive a null value of object because there is not a match between JSON and object of a class. My question is, how to get original JSON request when a user sends JSON with an incorrect format?
public class Document{
string name;
int number;
}
JSON REQUEST
{
"name":"Default name",
"number":91526861713"
}
JSON IS INCORRECT BECAUSE DATA TYPE OF number is int, not string "234" !
Automatically documentObject in function is equal to null.
How to get original JSON REQUEST?
[HttpPost]
public IHttpActionResult Receiving([FromBody]Document documentObject)
{
}
you can use Request.Content , But output is raw string.
like this:
[HttpPost]
public async Task<IHttpActionResult> Receiving([FromBody]Document documentObject)
{
var content = await Request.Content.ReadAsStringAsync();
return Json(content); // output => "name=xxx&number=123"
}
Here is my code:
[HttpGet]
[Produces("application/json")]
[Route("whatever")]
public ActionResult<JsonResult> Get()
{
string jsonText = "{\"city\":\"paris\"}";
return new JsonResult(JObject.Parse(jsonText));
}
This is the output I want:
{"city":"paris"}
This is the output I get:
{"contentType":null,"serializerSettings":null,"statusCode":null,"value":{"city":"paris"}}
How can I change my code to prevent .NET framework from wrapping my original JSON?
Then use a simpler and strongly typed result object instead of trying to manually create the JSON string.
[HttpGet]
[Produces("application/json")]
[Route("whatever")]
public IActionResult Get() {
var model = new { city = "paris" };
return Ok(model);
}
the framework will serialize the model to the desired output
There is no problem with ASP.NET MVC's JsonResult, but you're using JSON.NET. In JSON.NET, when you convert an json string vi JObject.Parse(), it returns a JObject object that contains some members. If you want to get the converted json, you should use ToString(), as the following:
[HttpGet]
[Produces("application/json")]
[Route("whatever")]
public ActionResult<JsonResult> Get()
{
string jsonText = "{\"city\":\"paris\"}";
return new JsonResult(JObject.Parse(jsonText).ToString());
}
I have a need to track emails and pages on our website. We want to use a WebAPI for this, however I am very new and the examples I found were hard to follow. Here is my problem:
I have an EmailTrackerContoller with code like below:
public class EmailTrackingController : Controller
{
[OutputCache(NoStore = true , Duration = 0)]
[HttpPost]
public ActionResult GetPixel(string email, Guid emailID) {
var client = new HttpClient();
var endpoint = "http://localhost:2640/api/EmailTracker/SaveEmail"; --path to my API
var response = await client.PostAsync(endpoint, null); --this does not work
const string clearGif1X1 = "R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
return new FileContentResult(Convert.FromBase64String(clearGif1X1) , "image/gif");
}
}
I have also created a WebAPI that has a HttpPost Method Called SaveEmail:
[HttpPost]
public HttpResponseMessage SaveEmail([FromBody]string value) { --How do I get the Email and Guid I need from here?
var a = new DL.EmailTracking();
a.Insert("<email>" , Guid.NewGuid());
return Request.CreateResponse(HttpStatusCode.Accepted , "");
}
Couple of questions on this:
How do you pass values from the controller to the WebApi?
Any easy to follow examples would be great, of if you have a link that would be useful as well.
The second parameter of PostAsync is the content of the call.
Serialize the object as JSON that contains the values you want and add it as the content.
var obj = new { Email = "mail#mail.com" };
HttpStringContent msg = new HttpStringContent(JsonConvert.SerializeObject(obj));
var response = await client.PostAsync(endpoint, msg);
Modify the receiving method to receive the desired properties. I'd use a class as the methods parameter but you can use [FromBody] with all the properties listed as well.
public HttpResponseMessage SaveEmail(EmailSave model)
I have a method that originally returned an HttpResponseMessage and I'd like to convert this to return IHttpActionResult.
My problem is the current code is using JSON.Net to serialize a complex generic tree structure, which it does well using a custom JsonConverter I wrote (the code is working fine).
Here's what it returns:
string json = NodeToJson(personNode);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
The NodeToJson method is where the custom converter comes into play ...
private static string NodeToJson(Node<Person> personNode) {
var settings = new JsonSerializerSettings {
Converters = new List<JsonConverter> { new OrgChartConverter() },
Formatting = Formatting.Indented
};
return JsonConvert.SerializeObject(personNode, settings);
}
Note this returns a string, formatted as JSON.
If I switch this to IHttpActionResult, it seems to fail regardless of what I try. I can just leave it (it works) but I am supposed to be using best practices for this and IHttpActionResult seems to be what I should be using.
I have tried to return Json(json); but this results in invalid, unparsable JSON, presumably because it's trying to do a double conversion?
return Ok(json); results in the JSON string being wrapped in XML.
What is the right way to do this?
EDIT:
I have successfully converted every method in this project to use IHttpActionResult now except this particular method.
It's a serialization of a generic tree to JSON. Regardless of what approach I try, I get back invalid JSON. The HttpResponseMsessage approach works fine, but I can not get valid JSON back with IHttpActionResult.
You can create your own IHttpActionResult class instance to return the JSON and a method in your controller or base controller class to utilize it.
Create the IHttpActionResult instance that sets the content and status code:
public class JsonTextActionResult : IHttpActionResult
{
public HttpRequestMessage Request { get; }
public string JsonText { get; }
public JsonTextActionResult(HttpRequestMessage request, string jsonText)
{
Request = request;
JsonText = jsonText;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
}
public HttpResponseMessage Execute()
{
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(JsonText, Encoding.UTF8, "application/json");
return response;
}
}
Add a method to your controller to create the result. Here is a Web API example:
public class MyApiController : ApiController
{
protected internal virtual JsonTextActionResult JsonText(string jsonText)
{
return new JsonTextActionResult(Request, jsonText);
}
[HttpGet]
public IHttpActionResult GetJson()
{
string json = GetSomeJsonText();
return JsonText(json);
}
}
Another recommendation is as below;
var json = JToken.FromObject(yourObject);
return Ok(json);
I've got the same problem and this piece of code worked for me (Using Newtonsoft.Json nuget package to deserialize the json):
var unserializedContent = JsonConvert.DeserializeObject(json);
return Json(unserializedContent);
It seems we must have an object in order to Json() work as it should.
Some of the solutions here are converting string to JSON, that's not necessary.
You are just using computer resources for nothing.
// Instead of
// return Ok(jsonstring);
// do:
HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(jsonstring, Encoding.UTF8, "application/json");
Request.RegisterForDispose(response); //To avoid the Pragma CA2000 warning
return ResponseMessage(response);
Another solution At client side
You can make a small change to be prepared to receive a string and convert it if necessary. The code bellow is Javascript
var data;
if (typeof weapiresponse == "string")
data = JSON.parse(weapiresponse);
else
data = weapiresponse;
If you have no intention of using XML as a return type, you can also remove the XmlFormatter in your WebApiConfig:
config.Formatters.Remove(config.Formatters.XmlFormatter);
The correct way is to return:
Ok(json);
It's converting the result to XML because that's the default accepted return type. Try adding:
Accept: application/json into your API request headers, I think that should resolve the issue.
I had the same problem with web-service returning JSON string in a XML-tag. I tried all the simple solutions Like :
return Json(text) , json deserialize and adding config.Formatter for json, but that did't help. I got double cotes around the json object or it was malformed.
Only the solution written by TGRA worked for me.
create your own IHttpActionResult class instance to return the JSON
For me, the only way to return an IHttpActionResult with the string content as Json in the following.
[HttpGet]
public IHttpActionResult ReturnStringAsJson()
{
return this.ResponseMessage(new HttpResponseMessage
{
Content = new StringContent("[json string]"),
Encoding.UTF8,
"application/json"),
});
}
I am new to ASP.NET MVC and learning. So far I have figured out how I can create a JSON Object and return that as a response to a request. However, I'm not able to pass a JSON body as part of a POST request like I normally did using Java.
Here is the code how I did this there -
#Path("/storeMovement")
#POST
#Consumes("application/json")
#Produces("application/json")
public String storeTrace(String json) {
JSONObject response = new JSONObject();
JSONParser parser = new JSONParser();
String ret = "";
try {
Object obj = parser.parse(json);
JSONObject jsonObj = (JSONObject) obj;
RecordMovement re = new RecordMovement((double) jsonObj.get("longitude"), (double) jsonObj.get("latitude"), (long) jsonObj.get("IMSI"));
ret = re.Store();
// Clear object
re = null;
System.gc();
response.put("status", ret);
} catch (Exception e) {
response.put("status", "fail " + e.toString());
}
return response.toJSONString();
}
I tried the same in the ASP.NET Action method but the value in the string parameter a is null as seen while debugging. Here's the code for the Action method -
public string Search(string a)
{
JObject x = new JObject();
x.Add("Name", a);
return x.ToString();
}
It works fine when I use an Object (for example - Book) like so -
public string Search(Book a)
{
JObject x = new JObject();
x.Add("Name", a.Name);
return x.ToString();
}
In that case, the book's name gets de-serialized just fine as I would expect. The class definition for the Book class -
public class Book
{
public int ID { get; set; }
public string Name { get; set; }
}
Can somebody please advise what I'm doing wrong? Is there no way to take in a string and then de-serialize? I'd like to be able to take in JSON without having to use an Object
As for as understand you want pass entire of request body to a string without any binding so you could handle passed string data with your desired way.
To aim this purpose simply write your own model binder:
public class RawBodyBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if(typeof(string)!=bindingContext.ModelType)
return null;
using (var s = new StreamReader(controllerContext.HttpContext.Request.InputStream))
{
s.BaseStream.Position = 0;
return s.ReadToEnd();
}
}
}
And in you action method assign your binder to desired parameter:
public string MyAction([ModelBinder(typeof(RawBodyBinder))]string json)
{
}
But MVC has own JSON model binder as well if your data is a standard JSON and in request body with Content-Type: application/json header you could use MVC's JSON model binder to activate JSON model binder simply add following line in Global.asax.cs file:
protected void Application_Start()
{
// some code here
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
}
The first thing in asp.net mvc to post a data is to decorate the method with this attribute [Httpost]
it's mean passing a string
should look like
[HttpPost]
public string Search(string a){
// your code
}
The default value is [HttpGet] that get parameters from url. For Post request you need to.
Edit:
And look the answer from vinayan
with jquery:
$.ajax({
method: "POST",
url: "Home/Search",
data: {'a': 'yourstring'}
})
The name of the parameter you send is used for the de-serialization. So in in this case, "a" should be part of json.
public string Search(string a)
so you will have to use,
$.ajax({
method: "POST",
url: "Home/Search",
data: {'a': 'yourstring'}
})