I am developing an application using ASP.NET MVC 4 and it involves web API call where the result I am getting for a specific record is a Json string. I am doing this web API call inside an action method of a controller and the result I am getting for such call is in the following form:
result = "{\"fname\":\"John\",\"lname\":\"Doe\",\"empno\":123456,\"dept\":\"IT\"}"
I am new to MVC and Json and would really appreciate any help on how I can extract specific values from this Json string such as the value for dept?
Thanks.
In order to use this as an actual object in your project you will need to deserialize this string. .NET has it's own deserialization or you can check out Json.Net which is pretty simple to figure out. Check out the documentation on JsonConvert.DeserializeObject<>...
ie...
Instructor desInst = new Instructor();
responseContent = rsp.Content.ReadAsStringAsync().Result;
desInst = JsonConvert.DeserializeObject<Instructor>(responseContent);
Related
I have a WebJob that is posting a JSON object to a controller in my MVC website.
The default ModelBinder is not working correctly in this instance. Rather than troubleshoot the binder, I am perfectly happy to handle the serialization myself.
How do I get the body of the POST request from my controller Action so that I can feed it into JSON.net?
I have tried using a StreamReader on Request.InputStream, but I get an empty string.
I'm using Angular.js $http.Post() to send a json object to my actionresult, and the Model Binding was failing. I used the below code and was able to get the json object posted and then use Newtonsoft for the DeSerialization. Interesting thing is that Newtonsoft didn't throw an error on Deserialization while the default model binding in MVC did.
var req = Request.InputStream;
var json = new StreamReader(req).ReadToEnd();
var result = JsonConvert.DeserializeObject<Model>(json);
This question already has answers here:
Setting the default JSON serializer in ASP.NET MVC
(2 answers)
Closed 8 years ago.
I just solved a recent problem where Json.Net allows me to include the 'type' of an object when it serializes it going to the Client. The reason for this is that the class that I'm sending back and forth has a property that is typed as a BaseClass to 4 Subclasses. The great thing now is that my client is showing each one correctly with the type attribute on the Json.
Now I need to send the object back to my Controller, not to an API controller. I've seen a bunch of posts about the api controller using Json.Net as the default JsonFormatter, but this doesn't work for a regular MVC Controller.
So my question is....How can I get my Controller to use the Json.Net Serializer by default? And...will this cause an issue for other items potentially making ajax calls?
I was able to send my json back to my controller as a string and then use JsonConvert to Deserialize my object successfully, so I know it can be done.
Any thoughts are appreciated.
EDIT:
Ok, so I followed the instructions here to change out the JsonValueProviderFactory and that seems to be working, however its not helping the original issue.
The problem is that the JsonFormatter is still the old one and not using Json.Net. So the ProviderFactory is building the dictionary correctly, but when it tries to Deserialize my object, I'm only getting my properties cast as the BaseClass, and not the Derived Class that I'm expecting.
Thoughts on that part?
EDIT:
Simply...how do I create my own JsonNetMediaTypeFormatter in MVC4? I've changed the ProviderFactory, but that only changes how each individual parameter is serialized to its corresponding value. What I need to do is to use Json.Net so that my Parameters that are typed as a Hierarchy is serialized to the correct derived class...not typed as the Baseclass.
Edit - Last:
Ok...so I did verify that if I call an ApiController, it maps the incoming parameter with the correct subclass. So, I can go this route, but I'd really like to find a way to have the same result with my regular Controller.
I had the same issue and resolved it by simply overriding the Json method on my base controller class.
EX:
protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
{
var result = new JsonNetResult
{
Data = data,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior
};
return result;
}
I understand that MVC4 can automatically bind json to type models.
For example, take an HTMLItem model.
In part of a method I retrieve the HTMLItem model data in json format from an external site using HttpRequest and StreamReader. I grab this as a string and then want to pass it into another method that takes HTMLItem as a parameter.
How do I ensure that the receiving method handles this as the type I require (HTMLItem)? It currently doesn't recognise it as such.
I tried assigning the string to the model in the originating method, but the IDE gives me the red squiggly for assigning a string to another type.
I don't want to have to go through the json string and assign each field manually if possible.
Any help, as always, much appreciated. Thanks.
You could deserialize the JSON to your model like:
using System.Web.Script.Serialization;
...
JavaScriptSerializer serializer = new JavaScriptSerializer();
YourModelType model = serializer.Deserialize<YourModelType>(yourJSON);
I spent a some time today looking through various HMAC implementations in C# for an upcoming WebAPI project. I wanted to start out with some existing code just to see it all work and understand it better before I either wrote it from scratch or modified it for my needs.
There are a bunch of great articles and posts both here and on the web. However, I have gotten to the point that I need some pointers and would greatly appreciate some insight.
I started with Cuong's post here: How to secure an ASP.NET Web API.
I knew I would have to expand upon it since I wanted to support both json and formencoded data. My test client is also written in C# using HttpClient and I spun up an empty WebAPI project and am using the ValuesController.
Below are my observations and questions:
POSTing: In order to get Cuong's code to work (validate successfully), my POST needs to include the parameters in the URL, however in order to get the values to my controller, I need to include them in the body. Is this normal for this type of authentication? In this particular instance, the message I am hashing is http://:10300/api/values?param1=value1¶m2=value2. Now I can parse the query string manually to get them, however in order to get the value to my controller through binding, I must also:
var dict = new Dictionary<string, string>
{
{"param1", "value1"},
{"param2", "value2"}
};
var content = new FormUrlEncodedContent(dict);
var response = await httpClient.PostAsync(httpClient.BaseAddress, content);
Otherwise my parameter is always null in the post action of the ValuesController.
I am planning on expanding the code to include a nonce. Between the combination of a nonce, a timestamp and the verb, is that enough for a secure hash? Is there really a need to also hash the message?
I tried (very unsuccessfully) to extend the code to support json as well as form encoded data and I must be missing something obvious.
Cuong is using the Authentication and Timestamp headers instead of putting the signature and timestamp in the query string. Is there a benefit to one method over the other? The majority of articles I have read have them in the query string itself.
The code looks great and I am a little out of my element here. I might be safer (saner?) just writing it from scratch to appreciate the nuances of it. That said, if anyone can lend some insight into what I am seeing that would be great.
At the end of the day, I want to be able to use the built in authorization mechinism of the WebAPI framework to simply attribute the methods/controllers, be able to accept form encoded and json data and reasonably model bind for complex types.
* Update *
I have done some more work today and below is the code from my nUnit PostTest. I figured out how to get the values through without both including them in the body and the query string (code below).
[Test]
public async void PostTest()
{
using (var httpClient = new HttpClient())
{
var payload = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"key1", "value1"},
{"key2", "value2"}
});
var now = DateTime.UtcNow.ToString("U");
httpClient.BaseAddress = new Uri(string.Format("http://ipv4.fiddler:10300/api/values"));
httpClient.DefaultRequestHeaders.Add("Timestamp", now);
httpClient.DefaultRequestHeaders.Add("Authentication", string.Format("test:{0}", BuildPostMessage(now, httpClient.BaseAddress, await payload.ReadAsStringAsync())));
var response = await httpClient.PostAsync(httpClient.BaseAddress, payload);
await response.Content.ReadAsStringAsync();
Assert.AreEqual(true, response.IsSuccessStatusCode);
}
}
I also figured out the model binding portion of it. There is a great article here: http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data that explains how POST works and I was able to get it to work with both a model of my own design as well as with the FormDataCollection object.
Now I am left wondering whether or not it is worth adding json encoded messages or if standardizing on FormUrlEncoding is the way to go. Also, are client nounce's enough or should I implement a server side nounce? Does a server side nounce double all of the calls to the service (first one throws a 401, second one includes the payload with the nounce?
I have an MVC project in which a controller action returns some JSON data (i.e. via /Home/GetData URL). This action also takes a custom object as a param.
This signature for the action is JsonResult GetData (MyCustomObject o)
I also have a client Silverlight project in which I'm constructing MyCustomObject and trying to call this URL (/Home/GetData/) via HttpWebRequest. However, I'm having trouble figuring out how to post in my object in this call. Do I need to serialize it to Json in order to pass it in?
Thanks so much!
MVC can accept and bind the submitted data to your MyCustomObject object, regardless of whether it is submitted as JSON, XML, a query string, a standard form POST, etc.
MVC does not require the object to be submitted in a particular fashion. That is up to you as the designer to determine what works best under the particular circumstances, given all of your requirements.
When submitted, MVC will use the ValueProvider suitable to the form of the data submitted, and the DefaultModelBinder will attempt to use the values in the ValueProvider to bind to your model.
Thanks for your help! Since the web app handles this with a getJSON call, I ended posting the object as a query string param i.e. I'm making a web request to http://../controller/action/view.aspx?custObject.property1=<value>&custObject.property2=<value> etc