trying to access an external JSON file using netwonsoft in mvc4 c# - json

I'm trying to read an external json to display data on screen. What am I doing worng here?
public void QuarterlyReport(object sender, EventArgs e)
{
JObject qData1 = JObject.Parse(System.IO.File.ReadAllText(#"~/json/quarterlyData.json"));
// read JSON directly from a file
using (StreamReader file = System.IO.File.OpenText(#"~/json/quarterlyData.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
JObject Qdata2 = (JObject) JToken.ReadFrom(reader);
}
string Qdata = Newtonsoft.Json.JsonConvert.SerializeObject(qData1);
}
public async Task<FileStreamResult> Index()
{
var _reportingService = new ReportingService("https://mysite.jsreportonline.net", "myemail#gmail.com", "password");
var report = await _reportingService.RenderAsync("VyxOYwH7Ze", new { Qdata });
//add the stream to be used by browser
MemoryStream ms = new MemoryStream();
//copy whatever JS is sending to us
report.Content.CopyTo(ms);
//start at content point
ms.Position = 0;
//send this to browser
return File(ms, report.ContentType.MediaType);
}
I can't seem to get the vaule into the variable Qdata. What is it that I am doing wrong in the method?

The line where you declare Qdata:
string Qdata = Newtonsoft.Json.JsonConvert.SerializeObject(qData1);
is not in the same scope as this line:
var report = await _reportingService.RenderAsync("VyxOYwH7Ze", new { Qdata });

Yes, the problem was that
JObject qData1 = JObject.Parse(System.IO.File.ReadAllText(#"~/json/quarterlyData.json"));
And
string Qdata = Newtonsoft.Json.JsonConvert.SerializeObject(qData1);
Needed to be in the same scope as
var report = await _reportingService.RenderAsync("VyxOYwH7Ze", new { Qdata });

Related

Images don't display in PDF

I have a fairly simple HTML page rendered via asp.net. It looks beautiful in the PDF after running it through HtmlRenderer.PdfSharp EXCEPT that the images don't appear. Just the red X of a missing image in the PDF even though the web page itself does display the image correctly.
Here is my HtmlRenderer.PdfSharp code:
public void BuildPDF( string url, string pdfPath ) {
string html = GetHTML(url);
Byte[] res = null;
using( MemoryStream ms = new MemoryStream() ) {
using( FileStream file = new FileStream(pdfPath, FileMode.Create, FileAccess.Write) ) {
byte[] bytes = new byte[ms.Length];
var pdf = TheArtOfDev.HtmlRenderer.PdfSharp.PdfGenerator.GeneratePdf(html, PdfSharp.PageSize.A4);
pdf.Save(ms);
res = ms.ToArray();
file.Write(res, 0, res.Length);
ms.Close();
}
}
}
private string GetHTML(string url) {
string html = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() )
using( Stream stream = response.GetResponseStream() )
using( StreamReader reader = new StreamReader(stream) ) {
html = reader.ReadToEnd();
}
return html;
}
And here is the img HTML that doesn't render in the PDF: <img src="images/ChartImg.png" />
How can I solve this?
Use the absolute path to the images.
<img src="http://example.org/images/ChartImg.png" />
You can parse the html and do a string replace first before passing it to the pdf converter.
The Code below:
var pdf = PdfGenerator.GeneratePdf(Html, PageSize.A4, 20, null, OnStylesheetLoad, OnImageLoadPdfSharp);
... ...
public static void OnImageLoadPdfSharp(object sender, HtmlImageLoadEventArgs e)
{
var url = e.Src;
if (!e.Src.StartsWith("http://") && !e.Src.StartsWith("https://"))
{
var ImgFilePath = System.Web.HttpContext.Current.Server.MapPath(url);
if (XImage.ExistsFile(ImgFilePath))
e.Callback(XImage.FromFile(ImgFilePath));
var ImgFilePath2 = System.Web.HttpContext.Current.Server.MapPath(url);
if (XImage.ExistsFile(ImgFilePath2))
e.Callback(XImage.FromFile(ImgFilePath2));
}
else
{
using (var client = new WebClient())
{
using (var stream = new MemoryStream(client.DownloadData(url)))
{
e.Callback(XImage.FromStream(stream));
}
}
}
}
It's better to use the image resolution callback for this for this:
var pdf = PdfGenerator.GeneratePdf(html, pdfConfig, imageLoad: OnImageLoad);
// snip
private void OnImageLoad(object sender, HtmlImageLoadEventArgs e)
{
using (var client = new WebClient())
{
var url = e.Src;
if (!e.Src.StartsWith("http://") && !e.Src.StartsWith("https://"))
{
url = Properties.Settings.Default.BaseUrl.TrimEnd('/') + e.Src;
}
using (var stream = new MemoryStream(client.DownloadData(url)))
{
e.Callback(XImage.FromStream(stream));
}
}
}
I'm late for your problem but maybe this will help someone else.
I used absolute urls and they were correct. Images were loaded correctly when I opened html file in browser.
However, they were not loaded after I converted this html to pdf. So I tried to use image resolution callback like #ohjo suggested. An exception occured here: An existing connection was forcibly closed by the remote host.
I was able to solve this but adding one more line that sets SecurityProtocol to this solution:
var pdf = PdfGenerator.GeneratePdf(Html, PageSize.A4, 20, null, OnStylesheetLoad, OnImageLoadPdfSharp);
... ...
public static void OnImageLoadPdfSharp(object sender, HtmlImageLoadEventArgs e)
{
var url = e.Src;
if (!e.Src.StartsWith("http://") && !e.Src.StartsWith("https://"))
{
var ImgFilePath = System.Web.HttpContext.Current.Server.MapPath(url);
if (XImage.ExistsFile(ImgFilePath))
e.Callback(XImage.FromFile(ImgFilePath));
var ImgFilePath2 = System.Web.HttpContext.Current.Server.MapPath(url);
if (XImage.ExistsFile(ImgFilePath2))
e.Callback(XImage.FromFile(ImgFilePath2));
}
else
{
using (var client = new WebClient())
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var stream = new MemoryStream(client.DownloadData(url)))
{
e.Callback(XImage.FromStream(stream));
}
}
}
}

Why are PostAsJsonAsync's parameters not included in the post as JSON content?

IT is very disapointing that after one week i cannot solve a simple problem of posting a JSON content to a Web Server's API. I think I will quit this attempt to use Xamarin.
I am trying to post the JSON parameters below using PostAsJsonAsync in a Xamarin app. The program does post the site but the parameters are not encoded as JSON content. Does anyone know why?
public async void Login()
{
var formcontent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string,string>("email","marcio#netopen.com.br"),
new KeyValuePair<string, string>("password","Xy345")
});
var FlyVIPAPI = new HttpClient();
var request = await FlyVIPAPI.PostAsJsonAsync("http://www.ik.com.br/app/api/LoginUser.php", formcontent);
var response = await request.Content.ReadAsStringAsync();
//var res = JsonConvert.DeserializeObject(response);
var RepostaJson = Newtonsoft.Json.Linq.JObject.Parse(response);
System.Diagnostics.Debug.WriteLine(RepostaJson["success"]);
System.Diagnostics.Debug.WriteLine(RepostaJson["error"]);
return;
}
public class LoginRequest
{
public string email { get; set; }
public string password { get; set; }
}
public async void Login()
{
using (var FlyVIPAPI = new HttpClient())
{
// Create Request object
var requestObj = new LoginRequest { email = "marcio#netopen.com.br", password = "Xy345" };
// Serialize to JSON string
var formcontent = JsonConvert.SerializeObject(requestObj);
// Create HTTP content
var content = new StringContent(formcontent, Encoding.UTF8, "application/json");
// POST Request
var request = await FlyVIPAPI.PostAsync("http://www.ik.com.br/app/api/LoginUser.php", content);
// Read Response
var response = await request.Content.ReadAsStringAsync();
....
}
}
Additionally, I would suggest wrapping your HttpClient in a using statement so that is will be disposed of once your code block is done. Freeing up resources.

In Aspose, when exporting document to html, how can I access multiple images in stream

When I use Aspose.Word to export a .docx with multiple images into html, I can save those images into MemoryStream, for example, I can use IImageSavingCallback as
var imagesStream = new MemoryStream();
var handleImageSaving = new HandleImageSaving(imagesStream);
options.ImageSavingCallback = handleImageSaving;
document.Save(stream, options);
public class HandleImageSaving : IImageSavingCallback
{
private MemoryStream m_images;
public HandleImageSaving(
MemoryStream i_images)
{
m_images = i_images;
}
void IImageSavingCallback.ImageSaving(ImageSavingArgs args)
{
args.ImageStream = m_images;
args.KeepImageStreamOpen = true;
}
}
After .Save is executed, multiple images are stored in imagesStream, now I need to retrieve image one by one from imagesStream, how can I do it?
Please try using the following sample:
Document doc = new Document(MyDir + #"input.docx");
MemoryStream htmlStream = new MemoryStream();
MemoryStream imagesStream = new MemoryStream();
HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.Html);
var handleImageSaving = new HandleImageSaving(imagesStream);
options.ImageSavingCallback = handleImageSaving;
doc.Save(htmlStream, options);
DocumentBuilder builder = new DocumentBuilder();
foreach (Stream imgStream in handleImageSaving.ImageStreams)
{
builder.InsertImage(imgStream);
builder.Writeln();
}
builder.Document.Save(MyDir + #"15.12.0.docx");
And the definition of HandleImageSaving class is as follows
public class HandleImageSaving : IImageSavingCallback
{
public ArrayList ImageStreams;
private MemoryStream m_images;
public HandleImageSaving(MemoryStream i_images)
{
ImageStreams = new ArrayList();
m_images = i_images;
}
void IImageSavingCallback.ImageSaving(ImageSavingArgs args)
{
Shape shape = (Shape)args.CurrentShape;
m_images = new MemoryStream(shape.ImageData.ImageBytes);
ImageStreams.Add(m_images);
args.ImageStream = m_images;
args.KeepImageStreamOpen = true;
}
}
Hope, this helps. I work with Aspose as Developer Evangelist.

Windows Phone 8 append to JSON file

I'm working on a Windows Phone 8 app.
I'm having issue appending to my JSON file.
It works fine if I keep the app open but once I close it and come back in it starts back writing from the beginning of the file.
Relevant code:
private async void btnSave_Click(object sender, RoutedEventArgs e)
{
// Create a entry and intialize some values from textbox...
GasInfoEntries _entry = null;
_entry = new GasInfoEntries();
_entry.Gallons = TxtBoxGas.Text;
_entry.Price = TxtBoxPrice.Text;
_GasList.Add(_entry);
//TxtBlockPricePerGallon.Text = (double.Parse(TxtBoxGas.Text) / double.Parse(TxtBoxPrice.Text)).ToString();
// Serialize our Product class into a string
string jsonContents = JsonConvert.SerializeObject(_GasList);
// Get the app data folder and create or open the file we are storing the JSON in.
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile textfile = await localFolder.CreateFileAsync("gasinfo.json", CreationCollisionOption.OpenIfExists); //if get await operator error add async to class (btnsave)
//open file
using (IRandomAccessStream textstream = await textfile.OpenAsync(FileAccessMode.ReadWrite))
{
//write JSON string
using (DataWriter textwriter = new DataWriter(textstream))
//using (DataWriter textwriter = new DataWriter(textstream))
{
textwriter.WriteString(jsonContents);
await textwriter.StoreAsync(); //writes buffer to store
}
}
}
private async void btnShow_Click(object sender, RoutedEventArgs e)
{
StorageFolder localfolder = ApplicationData.Current.LocalFolder;
try
{
// Getting JSON from file if it exists, or file not found exception if it does not
StorageFile textfile = await localfolder.GetFileAsync("gasinfo.json");
using (IRandomAccessStream textstream = await textfile.OpenReadAsync())
{
//read text stream
using (DataReader textreader = new DataReader(textstream))
{
//get size ...not sure what for think check the file size (lenght) then based on next 2 commands waits until its all read
uint textlength = (uint)textstream.Size;
await textreader.LoadAsync(textlength);
//read it
string jsonContents = textreader.ReadString(textlength);
// deserialize back to gas info
_GasList = JsonConvert.DeserializeObject<List<GasInfoEntries>>(jsonContents) as List<GasInfoEntries>;
displayGasInfoEntries();
}
}
}
catch
{
txtShow.Text = "something went wrong";
}
}
private void displayGasInfoEntries()
{
txtShow.Text = "";
StringBuilder GasString = new StringBuilder();
foreach (GasInfoEntries _entry in _GasList)
{
GasString.AppendFormat("Gallons: {0} \r\n Price: ${1} \r\n", _entry.Gallons, _entry.Price); // i think /r/n means Return and New line...{0} and {1} calls "variables" in json file
}
txtShow.Text = GasString.ToString();
}
Thanks
Do you call the btnShow_Click each time you've started the app? Because otherwise the _GasList will be empty; if you now call the btnSave_Click all previous made changes will be lost.
So please make sure, that you restore the previously saved json data before you add items to the _GasList.

View SharePoint 2010 list in JSON format

I am preparing to using Timeglider to create a timeline. One requirement is the data has to be in JSON format. One requirement for me is it needs to be client side as I do not have access to the servers or central admin.
When I try to do http://webname/_vti_bin/ListData.svc/listname I get an error for access permissions however when I issue it http://webname/subsite/_vti_bin/ListData.svc/listname I have no problem pulling data.
My situation is the list is on the TLD. I tried to follow this post How to retrieve a json object from a sharepoint list but it relates to SP 2007.
To implement pure JSON support in SharePoint 2007, 2010 and so on have a look at this project, http://camelotjson.codeplex.com/. It requires the commercial product Camelot .NET Connector to be installed on the server.
If you don't like to go commercial you can resort to the sp.js library, here is a small example I wrote, enjoy!
// Object to handle some list magic
var ListMagic = function () {
/* Private variables */
var that = this;
var clientContext = SP.ClientContext.get_current();
var web = clientContext.get_web();
var lists = web.get_lists();
/**
* Method to iterate all lists
*/
that.getLists = function () {
clientContext.load(lists);
clientContext.executeQueryAsync(execute, getFailed);
function execute() {
var listEnumerator = lists.getEnumerator();
while (listEnumerator.moveNext()) {
var l = listEnumerator.get_current();
// TODO! Replace console.log with actual routine
console.log(l.get_title());
}
}
function getFailed() {
// TODO! Implement fail management
console.log('Failed.');
}
};
/**
* Method to iterate all fields of a list
*/
that.getFields = function (listName) {
// Load list by listName, if not stated try to load the current list
var loadedList = typeof listName === 'undefined' ? lists.getById(SP.ListOperation.Selection.getSelectedList()) : that.lists.getByTitle(listName);
var fieldCollection = loadedList.get_fields();
clientContext.load(fieldCollection);
clientContext.executeQueryAsync(execute, getFailed);
function execute() {
var fields = fieldCollection.getEnumerator();
while (fields.moveNext()) {
var oField = fields.get_current();
// TODO! Replace console.log with actual routine
var listInfo = 'Field Title: ' + oField.get_title() + ', Field Name: ' + oField.get_internalName();
console.log(listInfo);
}
}
function getFailed() {
// TODO! Implement fail management
console.log('Failed.');
}
};
/**
* Method to get a specific listitem
*/
that.getListItem = function (itemId) {
var loadedList = lists.getById(SP.ListOperation.Selection.getSelectedList());
var spListItem = loadedList.getItemById(itemId);
clientContext.load(spListItem);
clientContext.executeQueryAsync(execute, getFailed);
function execute() {
// TODO! Replace console.log with actual routine
//spListItem.get_fieldValues()
console.log(spListItem.get_fieldValues()["Title"]);
}
function getFailed() {
// TODO! Implement fail management
console.log('Failed.');
}
};
/**
* Method to fake an init (optional)
*/
that.init = function () {
// Run any init functionality here
// I.e
that.getFields("Tasks");
};
return that;
};
// In case of no jquery use window.onload instead
$(document).ready(function () {
ExecuteOrDelayUntilScriptLoaded(function () {
var sp = new ListMagic();
sp.init();
}, 'sp.js');
});
Personally, I make HttpHandlers. I install them in the SharePoint isapi folder and the GAC and I can call them just like you might the owssvr.dll. http://servername/_vti_bin/myhttphandelr.dll
Pass it querystring variables or call it from jquery ajax. You can use the httpcontext and make a spcontext from it and have access to all sorts of information from the current location in SharePoint. Then you can javascriptserialize the objects and pass them as JSON. Looking for some code... Hang on... I can't put all the code but this should get you close. I use this to add a submenu to the context menu to allow a user to delete or rename a file if they uploaded it to a library and it is version 1.0 and to collect a file from a library and create a eml file with the selected file(s) as an attachment(s). We don't give our users delete privileges normally. Point being, you can now create a class with just the information you need from SharePoint and pass it as JSON. The only downfall I have with this, is iisreset is required if you make any changes to the dll.
I task schedule a iisreset every night at midnight anyway to keep it fresh and free from memory bloat. I come in the next day and my changes are there. The cool thing is, the spcontext has information about the current location in SharePoint from where it is called. So, http://servername/_vti_bin/myhttphandelr.dll vs http://servername/subsite/library/_vti_bin/myhttphandelr.dll
I might add. Don't try to serialize SharePoint objects. One they are huge, complex objects. Two, I don't think they are marked serializable. Just make you own class and populate it with the values you need from the SharePoint objects.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Web;
using System.Web.Script.Serialization;
using ADODB;
using interop.cdosys;
using Microsoft.SharePoint;
namespace owssvr2
{
public class OWSsvr2 : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
private string cmd;
ctx ctx = new ctx();
private string currentuser;
private SPContext SPcontext;
private HttpContext cntx;
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
SPcontext = SPContext.GetContext(context); <-- Gets spcontext from the httpcontext
cntx = context;
ctx = GetData(context.Request); <-- I parse some information from the request to use in my app
cmd = ctx.Cmd;
ctx.User = context.User.Identity.Name;
currentuser = context.User.Identity.Name;
switch (cmd)
{
case "Delete":
Delete();
context.Response.Redirect(ctx.NextUsing);
break;
case "HasRights":
HasRights();
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
string serEmployee = javaScriptSerializer.Serialize(ctx);
context.Response.Write(serEmployee);
context.Response.ContentType = "application/json; charset=utf-8";
break;
case "Rename":
Rename(context);
//context.Response.Redirect(context.Request["NextUsing"]);
break;
case "SendSingleFile":
try
{
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.BufferOutput = true;
ADODB.Stream stream = SendSingleFile(context.Request["URL"]);
stream.Type = StreamTypeEnum.adTypeBinary;
stream.Position = 0;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment;filename=Email.eml");
IStream iStream = (IStream)stream;
byte[] byteArray = new byte[stream.Size];
IntPtr ptrCharsRead = IntPtr.Zero;
iStream.Read(byteArray, stream.Size, ptrCharsRead);
context.Response.BinaryWrite(byteArray);
context.Response.End();
}
catch(Exception ex) {context.Response.Write(ex.Message.ToString()); }
break;
case "SendMultiFile":
try
{
//SendMultiFile(context.Request["IDs"]);
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.BufferOutput = true;
ADODB.Stream stream = SendMultiFile(context.Request["IDs"]);
stream.Type = StreamTypeEnum.adTypeBinary;
stream.Position = 0;
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment;filename=Email.eml");
IStream iStream = (IStream)stream;
byte[] byteArray = new byte[stream.Size];
IntPtr ptrCharsRead = IntPtr.Zero;
iStream.Read(byteArray, stream.Size, ptrCharsRead);
context.Response.BinaryWrite(byteArray);
context.Response.End();
}
catch(Exception ex) {context.Response.Write("There was an error getting the files. </br>" + ex.Message.ToString()); }
break;
case "FileInfo":
JavaScriptSerializer javaScriptSerializer1 = new JavaScriptSerializer();
string serEmployee1 = javaScriptSerializer1.Serialize(FileInfo(context));
context.Response.Write(serEmployee1);
context.Response.ContentType = "application/json; charset=utf-8";
break;
case "UsersInGroups":
UsersInGroups ug = new UsersInGroups(context, context.Request["job"],context.Request["groups"]);
break;
}
}