ASP.NET MVC 4 return Json resulting in double json or empty data - asp.net-mvc-4

I am getting either empty Json results or double json results and I don't know why yet?
base line:
http://learn.knockoutjs.com/mail?folder=Inbox
looks like this in chrome F12: {"id":"Inbox","mails":[{"id":1,......}
My Action:
public ActionResult Mail()
{
string qs = "";
foreach (var q in Request.QueryString)
{
qs += string.Format("{0}={1}&", q, Request.QueryString[q.ToString()]);
}
var proxyRequest = "http://learn.knockoutjs.com/mail?" + qs;
var request = WebRequest.Create(proxyRequest);
var response = (HttpWebResponse)request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
var str = reader.ReadToEnd();
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(str);
//var json = JsonConvert.SerializeObject(data);
// Text Visualization looks good {"id":"Inbox","mails":[{"id":1,"from":"Abb....}
// no outside quotes, no escaped quotes
var res = Json(data, JsonRequestBehavior.AllowGet);
return res;
}
So basically I am proxying the call, but the question is why is the result coming back as either not filled in or double jsoned.
using chrome network trace the result of the above looks like.
[[[]],[[[[[]],[[]],[[]],[[]],[[]],...]
valid json, just empty.
when I change the code to look like this
var json = JsonConvert.SerializeObject(data);
// Text Visualization looks good {"id":"Inbox","mails":[{"id":1,"from":"Abb....}
// no outside quotes, no escaped quotes
var res = Json(json, JsonRequestBehavior.AllowGet);
return res;
Chrome network trace has doubled jsoned the data.
"{\"id\":\"Inbox\",\"mails\":[{\"id\":1,\"from\":\"Ab....}"
Since I don't know what the Json actually is, I did newton soft dynamic convert
JsonConvert.DeserializeObject
That may be the problem behind my empty response?
Any help would really be appreciated.
Thanks

Your first method is failing because Json() doesn't understand the dynamic object returned from your JSON reader.
Your second method is failing because Json() is serializing a pre-serialized string.
You can return pre-serialized JSON data using Content(jsonString, "application/json")

Related

Get string returned from a PostAsync event

I'm using HttpClient like this in my console app:
using (var http = new HttpClient(handler))
{
http.BaseAddress = new Uri("http://127.0.0.1:34323/");
var response = await http.PostAsync("/api/generate", new StringContent(
JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"));
Console.WriteLine(response.Content.ToString());
}
In debug mode, I can see that the controller is returning a string of JSON.
However, I only get this written to the console:
System.Net.Http.StreamContent
How can I get it to write the actual JSON that's being returned?
Thanks!
Try below line:
Console.WriteLine(response.Content.ReadAsStringAsync().Result.ToString());

Marketo rest Api create lead

I have a question about this create/Update leads API, http://developers.marketo.com/documentation/rest/createupdate-leads/.
There is no sample code for C# or JAVA. Only ruby available. So I have to try it by myself. But I always get null return from the response.
Here is my code:
private async Task<CreateLeadResponseResult> CreateLead(string token)
{
string url = String.Format(marketoInstanceAddress+"/rest/v1/leads.json?access_token={0}", token);
var fullUri = new Uri(url, UriKind.Absolute);
CreateLeadResponseResult createLeadResponse = new CreateLeadResponseResult();
CreateLeadInput input = new CreateLeadInput { email = "123#123.com", lastName = "Lee", firstName = "testtesttest", postCode = "00000" };
CreateLeadInput input2 = new CreateLeadInput { email = "321#gagaga.com", lastName = "Lio", firstName = "ttttttt", postCode = "00000" };
List<CreateLeadInput> inputList = new List<CreateLeadInput>();
inputList.Add(input);
inputList.Add(input2);
CreateLeadRequest createLeadRequest = new CreateLeadRequest() { input = inputList };
JavaScriptSerializer createJsonString = new JavaScriptSerializer();
string inputJsonString = createJsonString.Serialize(createLeadRequest);
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(fullUri.OriginalString, inputJsonString).ConfigureAwait(false);
// I can see the JSON string is in the message body in debugging mode.
if (response.IsSuccessStatusCode)
{
createLeadResponse = await response.Content.ReadAsAsync<CreateLeadResponseResult>();
}
else
{
if (response.StatusCode == HttpStatusCode.Forbidden)
throw new AuthenticationException("Invalid username/password combination.");
else
throw new ApplicationException("Not able to get token");
}
}
return createLeadResponse;}
//get null here.
Thank you.
-C.
The best way to debug this is to capture the exact URL, parameters and JSON that are submitted by your app and try submitting those manually via a tool like Postman (Chrome plug-in) or SOAP UI. Then you see the exact error message, which you can look up here: http://developers.marketo.com/documentation/rest/error-codes/. Based on that you can update your code. I don't know much about Java, but this is how I got my Python code to work.
Your example code was really helpful in getting my own implementation off the ground. Thanks!
After playing with it for a bit, I realized that the JavaScriptSerializer step is unnecessary since PostAsJsonAsync automatically serializes whatever object you pass to it. The double serialization prevents Marketo's API from processing the input.
Also, I agree with Jep that Postman is super helpful. But in the case of this error, Postman was working fine (using the contents of inputJsonString) but my C# code still didn't work properly. So I temporarily modified the code to return a dynamic object instead of a CreateLeadResponseResult. In debugging mode this allowed me to see fields that were discarded because they didn't fit the CreateLeadResponseResult type, which led me to the solution above.

PDF generation in mvc4 with itextsharp

I am working on pdf generation, it is successfully implemented using itextsharp.dll. It’s working fine on local environment after publish also. We have our own server at other site
But same code doesn't work on the server,pdf is not generated instead it gives an error: 'The document has no pages.'
Initially I thought it is due to no data in document but it works locally with or without data in the document.
I had code implemented as follows to make a web request Is any problem in that ??
try
{
var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(strPdfData + "?objpatId=" + patID);
var response = myHttpWebRequest.GetResponse();
myHttpWebRequest.Timeout = 900000;
var stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
content = sr.ReadToEnd();
}
create a method in the controller:
[HttpGet]
public JsonResult GetFile()
{
var json = new WebClient().DownloadFile(string address, string fileName);
//This code is just to convert the file to json you can keep it in file format and send to the view
dynamic result = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
var oc = Newtonsoft.Json.JsonConvert.DeserializeObject<countdata[]>(Convert.ToString(result.countdata));
return Json(oc, JsonRequestBehavior.AllowGet);
}
In the view just call this function:
#Url.Action('genPDF','GetFile');

Sending Commands from an MVC4 site to Another

I have two sites: one of them controls the other sending some commands through Web API. The idea is: the action of the controller site sends a command to the other site, gets the response and perform some business rules, without redirecting to the other site.
I have tons of examples explaining how to implement this via jQuery, but I want to make the controller post the data to the other site, instead of the view.
I found an approach at this answer: How to use System.Net.HttpClient to post a complex type?, but I want the answer for an JSON approach.
Can someone post a simple example using JSON showing how to do this?
As I didn't find a brief answer to my question, I'll post the solution I've made.
As the method uses an HttpClient method that requires async statements, the action below was implemented retuning a Task<ActionResult>. Another modification is if you're saving an object in context.
Instead of using:
context.SaveChanges();
You'll have to use:
await context.SaveChangesAsync();
The code below implements an Action from an ASP.NET MVC4 Controller:
[HttpPost]
public async Task<ActionResult> Create(MyModel model)
{
if (ModelState.IsValid)
{
// Logic to save the model.
// I usually reload saved data using something kind of the statement below:
var inserted = context.MyModels
.AsNoTracking()
.Where(m => m.SomeCondition == someVariable)
.SingleOrDefault();
// Send Command.
// APIMyModel is a simple class with public properties.
var apiModel = new APIMyModel();
apiModel.AProperty = inserted.AProperty;
apiModel.AnotherProperty = inserted.AnotherProperty;
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(APIMyModel));
// use the serializer to write the object to a MemoryStream
MemoryStream ms = new MemoryStream();
jsonSer.WriteObject(ms, apiModel);
ms.Position = 0;
//use a Stream reader to construct the StringContent (Json)
StreamReader sr = new StreamReader(ms);
// Note if the JSON is simple enough you could ignore the 5 lines above that do the serialization and construct it yourself
// then pass it as the first argument to the StringContent constructor
StringContent theContent = new StringContent(sr.ReadToEnd(), System.Text.Encoding.UTF8, "application/json");
HttpClient aClient = new HttpClient();
Uri theUri = new Uri("http://yoursite/api/TheAPIAction");
HttpResponseMessage aResponse = await aClient.PostAsync(theUri, theContent);
if (aResponse.IsSuccessStatusCode)
{
// Success Logic. Yay!
}
else
{
// show the response status code
String failureMsg = "HTTP Status: " + aResponse.StatusCode.ToString() + " - Reason: " + aResponse.ReasonPhrase;
}
return RedirectToAction("Index");
}
// if Model is not valid, you can put your logic to reload ViewBag properties here.
}

how to read Data context parameter from a crm to silverlight webresource

i have a silverlight webresource in my crm 2011.
now my task is to append a data parameter in url like
https://www.............../data=1234
now in silverlight application i need to read this data parameter.
i have tried to read the data
if (App.Current.Host.InitParams["data"] != string.Empty)
{
string CallerNumber = App.Current.Host.InitParams["data"];
...
and
i tried filtering the code to like
string url = System.Windows.Browser.HtmlPage.Document.DocumentUri.ToString();
var uri = new Uri(url);
var CallerNumber = uri.Query;
callernumber will have the ?data=1234
but still i am not able to get the data parameter. Do help
I believe that you will find those in the query string. You can access it like this
foreach (var item in HtmlPage.Document.QueryString)
{
//Do something like the data
}