Subsonic 3 Newtonsoft JSON "Self referencing loop Exception" - linq

Hi I been searching for my error but I can't find anything that help me. The problem is this. I been working with Subsonic 3, Newtonsoft Json and the linq way of write so I have this easy query:
var found = from client in newclients.All() where client.Period == "sometext" select client;
string periodoJSON = JsonConvert.SerializeObject(periodoFound); //this get "Self referencing loop Exception"
the problem is when I run this script I get the horrible exception "Self referening loop exception" in the JsonConvert line, subsonic have all the objects without any problem but if I do the following.
var found = from client in newclients.All() where client.Period == "sometext" select new client{client.Name, client.LastName, etc};
string periodoJSON = JsonConvert.SerializeObject(periodoFound);
I get the object serialize with a any problem with all the properties. I'm doing the last way because I have to finish my work but is any other way or solution for this problem, if not I will have to write all the properties every time I want to get a full table properties.
hope any can solve my problem o help me in the path for find a solution....
what I have is a really basic query with linq and I try the three values for JsonSerializerSettings and any work, again I'm working with subsonic 3 this not happend either with subsnoic 2 and I can make it work if I specify one by one the properties of the object in the linq query does any have any clue of what is happend, ANY more help would be great!!! If I put the value of Serialize my page get crazy and in a infinity loop state, if I decide for error simple doesn't work and Ignore nothing happen... some more information about this self referencia loop?
var u = usuario.SingleOrDefault(x => x.TipoUsuario == "A" || x.TipoUsuario == "W");
JsonSerializerSettings setting = new JsonSerializerSettings();
setting.ReferenceLoopHandling = ReferenceLoopHandling.Error; //.Serialize .Ignore
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"usuario", "var usuario=" + JsonConvert.SerializeObject(u, Formatting.None, setting) + ";");
Update ------
I code the following
string jsU = JsonConvert.SerializeObject(u,Formatting.None,new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
and is workign but the only thing wrongs is that in the json object comes all the information about the columns of subsonic 3 and a BIG chunk of text explain it... does any one know how to not SEND this part of the object??

Without knowing more about you object model it is hard to provide a definitive answer, but I would take a look at the ReferenceLoopHandling enum.
You're calling string SerializeObject(object value) on JsonConvert. Try the string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) method instead. The JsonSerializerSettings settings parameter lets you set a bunch of things, including the ReferenceLoopHandling ReferenceLoopHandling { get; set; } property.
You can try these values:
public enum ReferenceLoopHandling
{
Error,
Ignore,
Serialize
}
Obviously, Error is the default and that's what you're getting. Perhaps one of the others will help.

Related

LINQ Query Result - dynamically get field value from a field name variable

LINQ newbie here
I am trying to get a value of a field - using a fieldName variable.
If I do a watch on row[FieldName] I do get a value - but when I do it on the actual code it will not compile.
string fieldName = "awx_name"
List<awx_property> propertyQry =
(
from property in crm.awx_propertyawx_properties
where property.awx_propertyid == new Guid(id)
select property
).ToList();
foreach (awx_property row in propertyQry)
{
//THIS DOES NOT WORK
fieldValue = row[fieldName];
}
Thanks in advance. Alternatives would be welcome as well
You keep us guessing what you are trying to do here... You need to specify the types of the objects, so it's easy for us to understand and help. Anyway, I think you are trying to get an object based on the ID. Since you are getting by Id, my guess would be the return value is a single object.
var propertyObj =( from property in crm.awx_propertyawx_properties
where property.awx_propertyid == new Guid(id)
select property
).SingleOrDefault();
if(propertyObj != null) {
fieldValue = propertyObj.GetType().GetProperty(fieldName).GetValue(propertyObj, null);
}
Of course, you need to add validation to make sure you don't get null or any other error while accessing the property value.
Hope it helps.
What type is fieldValue? What does awx_property look like? This will only work is awx_property is a key/value collection. It its not, you could use reflection instead.
If it is a key/value collection you are probably missing a cast. (row[FieldName].ToString() or something) Also you are missing a semi-colon in the foreach block.

WP7 Trouble populating pie chart

I'm having some trouble with populating a pie chart in my WP7 project. At the moment, my code is as follows below. I've tried a few different ways to bring the data back from an xml web service but no luck. Can anyone see what I have done wrong?
The error I'm getting right now is, "Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Xml.Linq.XElement'. An explicit conversion exists (are you missing a cast?)"
XDocument XDocument = XDocument.Load(new StringReader(e.Result));
XElement Traffic = XDocument.Descendants("traffic").First();
XElement Quota = XDocument.Descendants("traffic").Attributes("quota");
ObservableCollection<PieChartItem> Data = new ObservableCollection<PieChartItem>()
{
new PieChartItem {Title = "Traffic", Value = (double)Traffic},
new PieChartItem {Title = "Quota", Value = (double)Quota},
};
pieChart1.DataSource = Data;
my guess is this line has the compile error:
XElement Quota = XDocument.Descendants("traffic").Attributes("quota");
the result of Descendants("traffic") is an IEnumerable, not an XElement. in the line above that you're already getting First of that enumerable, which is the item you want, isn't it?
the quota line should be:
XElement Quota = Traffic.Attributes("quota");
Style wise, most people make local variables lower cased, like traffic and quota and data to distinguish them from class level properties and members.
Update: it looks like Attributes("quota") returns IEnumerable<XAttribute>, so that quota line should be:
XAttribute Quota = Traffic.Attributes("quota").FirstOrDefault();
or to simplify:
var traffic = XDocument.Descendants("traffic").First();
var quota = traffic.Attributes("quota").FirstOrDefault();
I don't want to be mean, but fixing compiler errors like this should be something you shouldn't have to come to stackoverflow for. The compiler error itself is telling you what the problem is: the method returns a type other than what you said it does. Using var can simplify some of that.

foreach in linq result not working

Don't know what's wrong here, when I run the application it says "Specified method is not supported" pointing at "var result in query" in foreach loop. Please help...
var query = from c in entities.Customer
select c.CustomerName;
List<string> customerNames = new List<string>();
foreach (var result in query)
{
customerNames.Add(result.ToString());
}
EDIT: using ToList() also gives the same error.
The reason for your error is scope, which is what the "method not supported" error is telling you.
This usually happens when using a Linq to [fill in the blank] ORM. So, I'm guessing your entities must be from an ORM tool, something like Entity Framework, and you are using something like Linq to Entities.
When using linq your query is not enumerated out until you access it, which for an ORM means hitting the database or other data repository. This delayed action can cause some strange behavior if you do not know it is there, such as this error.
But, you have local (non-linq) code and your query intertwined, so the linq to [] compiler does not know how to handle your local code when compiling the linq code. Thus the "method not supported" error - it is basically the same as referencing a private method from outside of the class, the method you called is unknown in the current scope.
In other words the compiler is trying to compile your query and hit the database when you do the result.ToString(), but does not know anything about the private variable of CustomerNames or the foreach method. The database logic and the local object logic have to be kept separate - completely resolve the database query results before using locally.
You should be able to write it like this:
var customerNames = entities.Customer.Select(c => c.CustomerName).ToList();
If you have to keep the foreach (for more complicated logic, not for this simple of an example) you still need to resolve the Linq to [] portion (by forcing it to enumerate the query results) prior to involving any non-linq code:
var query = from c in entities.Customer
select c.CustomerName;
var qryList = query.ToList();
List<string> customerNames = new List<string>();
foreach (var result in qryList)
{
customerNames.Add(result.ToString());
}
Can you try using just the ToList() method instead of the foreach?
List<string> customerNames = query.ToList();
If the problem is not ToString() as Gart mentioned my second suspicious falls in c.CustomerName. Is this a custom property in your partial class?
Also, the stacktrace of the exception must surly show what is the unsupported method.
Try removing .ToString() and see if this will work:
foreach (var result in query)
{
customerNames.Add(result);
}
Seems like that the root of the problem lies deep inside LINQ-to-SQL query translation mechanism. I suppose the translation engine tries to translate .ToString() into SQL and fails there.
try this
var query = from c in entities.Customer
select c.CustomerName;
List<string> customerNames = new List<string>();
query.ToList().ForEach(r=>customerNames.Add(r));

How to use Crystal Reports without a tightly-linked DB connection?

I'm learning to use Crystal Reports (with VB 2005).
Most of what I've seen so far involves slurping data directly from a database, which is fine if that's all you want to display in the report.
My DB has a lot of foreign keys, so the way I've tried to stay sane with presenting actual information in my app is to add extra members to my objects that contain strings (descriptions) of what the foreign keys represent. Like:
Class AssetIdentifier
Private ID_AssetIdentifier As Integer
Private AssetID As Integer
Private IdentifierTypeID As Integer
Private IdentifierType As String
Private IdentifierText As String
...
Here, IdentifierTypeID is a foreign key, and I look up the value in a different table and place it in IdentifierType. That way I have the text description right in the object and I can carry it around with the other stuff.
So, on to my Crystal Reports question.
Crystal Reports seems to make it straightforward to hook up to records in a particular table (especially with the Experts), but that's all you get.
Ideally, I'd like to make a list of my classes, like
Dim assetIdentifiers as New List(Of AssetIdentifier)
and pass that to a Crystal Report instead of doing a tight link to a particular DB, have most of the work done for me but leaving me to work around the part that it doesn't do. The closest I can see so far is an ADO.NET dataset, but even that seems far removed. I'm already handling queries myself fine: I have all kinds of functions that return List(Of Whatever) based on queries.
Is there an easy way to do this?
Thanks in advance!
UPDATE: OK, I found something here:
http://msdn.microsoft.com/en-us/library/ms227595(VS.80).aspx
but it only appears to give this capability for web projects or web applications. Am I out of luck if I want to integrate into a standalone application?
Go ahead and create the stock object as described in the link you posted and create the report (StockObjectsReport) as they specify. In this simplified example I simply add a report viewer (crystalReportViewer1) to a form (Form1) and then use the following code in the Form_Load event.
stock s1 = new stock("AWRK", 1200, 28.47);
stock s2 = new stock("CTSO", 800, 128.69);
stock s3 = new stock("LTWR", 1800, 12.95);
ArrayList stockValues = new ArrayList();
stockValues.Add(s1);
stockValues.Add(s2);
stockValues.Add(s3);
ReportDocument StockObjectsReport = new StockObjectsReport();
StockObjectsReport.SetDataSource(stockValues);
crystalReportViewer1.ReportSource = StockObjectsReport;
This should populate your report with the 3 values from the stock object in a Windows Form.
EDIT: Sorry, I just realized that your question was in VB, but my example is in C#. You should get the general idea. :)
I'm loading the report by filename and it is working perfect:
//........
ReportDocument StockObjectsReport;
string reportPath = Server.MapPath("StockObjectsReport.rpt");
StockObjectsReport.Load(reportPath);
StockObjectsReport.SetDataSource(stockValues);
//Export PDF To Disk
string filePath = Server.MapPath("StockObjectsReport.pdf");
StockObjectsReport.ExportToDisk(ExportFormatType.PortableDocFormat, filePath);
#Dusty had it. However in my case it turned out you had to wrap the object in a list even though it was a single item before I could get it to print. See full code example:
string filePath = null;
string fileName = null;
ReportDocument newDoc = new ReportDocument();
// Set Path to Report File
fileName = "JShippingParcelReport.rpt";
filePath = func.GetReportsDirectory();
// IF FILE EXISTS... THEN
string fileExists = filePath +#"\"+ fileName;
if (System.IO.File.Exists(fileExists))
{
// Must Convert Object to List for some crazy reason?
// See: https://stackoverflow.com/a/35055093/1819403
var labelList = new List<ParcelLabelView> { label };
newDoc.Load(fileExists);
newDoc.SetDataSource(labelList);
try
{
// Set User Selected Printer Name
newDoc.PrintOptions.PrinterName = report.Printer;
newDoc.PrintToPrinter(1, false, 0, 0); //copies, collated, startpage, endpage
// Save Printing
report.Printed = true;
db.Entry(report).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}
catch (Exception e2)
{
string err = e2.Message;
}
}

ADO.NET Data Services, LINQ

I have C# code to populate a dropdown list in Silverlight which works fine except when there are duplicates. I think because IEnumerable<Insurance.Claims> is a collection, it filters out duplicates. How would I code my LINQ query to accept duplicates?
My Sample Data looks like:
Code => CodeName
FGI Field General Initiative
SRI Static Resource Initiative
JFI Joint Field Initiative - This is "overwritten" in results
JFI Joint Friend Initiative
IEnumerable<Insurance.Claims> results;
// ADO.NET Data Service
var claim = (from c in DataEntities.Claims.Expand("Claimants").Expand("Policies")
where c.Claim_Number == claimNumber
select c);
DataServiceQuery<Insurance.Claims> dataServiceQuery =
claim as DataServiceQuery<Insurance.Claims>;
dataServiceQuery.BeginExecute((asyncResult) =>
{
results = dataServiceQuery.EndExecute(asyncResult);
if (results == null)
{
// Error
}
else
{
// Code to populate Silverlight form
}
});
(Not sure if you're still struggling with this but anyway...)
I'm pretty sure it's not the IEnumerable interface but the actual drop down that is causing this behaviour. The code is being used as the key, and so obviously each time the same code is encountered, the item is being overwritten.
I don't think you can override this unless you change the code, or use another identifier as the key field in the dropdown.
You may want to add a try-catch block around dataServiceQuery.EndExecute(asyncResult) to properly handle errors.

Resources