How Insert Detail Rows As Columns In DevExpress Reports - devexpress

I am using DevExpress reports and I need to insert two detail rows into one row, for example like this (1 column for each detail row):
------------------------------------
Detail1 | Detail2
------------------------------------
Currently when I insert detail row 2, it is insert under the detail row 1 for example this:
-----------------------------------
Detail1
-----------------------------------
Detail2
-----------------------------------
How can I solve this?

You can use XRSubreport objects for show two details in one row by placing two subreports side-by-side0. So, just put two XRSubreport objects to your DetailBand and use XRSubreport.BeforePrint event handler to provide the details data for subreports1.
Here is example:
public void ShowReport()
{
var masters = new List<Master>();
var random = new Random();
for (int index = 0; index < 100; index++)
{
var master = new Master() { ID = index, Name = "Master_" + index };
var detailCount = random.Next(1, 10);
for (int detailIndex = 0; detailIndex < detailCount; detailIndex++)
{
var detail0 = new Detail0() { ID = detailIndex, Name = "Detail_0_" + detailIndex };
master.Details0.Add(detail0);
}
detailCount = random.Next(1, 10);
for (int detailIndex = 0; detailIndex < detailCount; detailIndex++)
{
var detail1 = new Detail1() { ID = detailIndex, Name = "Detail_1_" + detailIndex };
master.Details1.Add(detail1);
}
masters.Add(master);
}
var report = new XtraReport();
var detailBand = CreateDetailBand(report, masters);
detailBand.HeightF = 40;
var detailReport0 = new XtraReport();
CreateDetailBand(detailReport0, null);
var subReport0 = new XRSubreport() { LocationF = new PointF(20, 20), WidthF = 150, ReportSource = detailReport0 };
subReport0.BeforePrint += (s, e) =>
{
var currentReport = ((XRSubreport)s);
var master = ((Master)currentReport.Report.GetCurrentRow());
currentReport.ReportSource.DataSource = master.Details0;
};
detailBand.Controls.Add(subReport0);
var detailReport1 = new XtraReport();
CreateDetailBand(detailReport1, null);
var subReport1 = new XRSubreport() { LocationF = new PointF(170, 20), WidthF = 150, ReportSource = detailReport1 };
subReport1.BeforePrint += (s, e) =>
{
var currentReport = ((XRSubreport)s);
var master = ((Master)currentReport.Report.GetCurrentRow());
currentReport.ReportSource.DataSource = master.Details1;
};
detailBand.Controls.Add(subReport1);
report.DataSource = masters;
report.ShowRibbonPreview();
}
public DetailBand CreateDetailBand(XtraReport report, object DataSource)
{
var detailBand = new DetailBand() { HeightF = 20 };
var label = new XRLabel();
label.DataBindings.Add(new XRBinding("Text", DataSource, "ID"));
detailBand.Controls.Add(label);
label = new XRLabel() { LeftF = 30 };
label.DataBindings.Add(new XRBinding("Text", DataSource, "Name"));
detailBand.Controls.Add(label);
report.Bands.Add(detailBand);
return detailBand;
}
public class Master
{
public Master()
{
Details0 = new List<Detail0>();
Details1 = new List<Detail1>();
}
public int ID { get; set; }
public string Name { get; set; }
public List<Detail0> Details0 { get; private set; }
public List<Detail1> Details1 { get; private set; }
}
public class Detail0
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Detail1
{
public int ID { get; set; }
public string Name { get; set; }
}
Here is screenshot:
0 How to: Create a Side-by-Side Report
1 How to: Create a Master-Detail Report using Subreports

Related

Get object from client validation attribute

I have next "AddValidation" method in client validation attribute (inherited from ValidationAttribute, IClientModelValidator)
public void AddValidation(ClientModelValidationContext context)
{
var viewContext = context.ActionContext as ViewContext;
var modelType = context.ModelMetadata.ContainerType;
var model = viewContext?.ViewData.Model;
var maxDate = (DateTime?)modelType.GetProperty(_maxDateName)?.GetValue(model, null);
var minDate = (DateTime?)modelType.GetProperty(_minDateName)?.GetValue(model, null);
var errorMessage = string.Format(ErrorMessageString, minDate?.ToString("MM/dd/yyyy"), maxDate?.ToString("MM/dd/yyyy"));
context.Attributes.Add("data-val-preliminaryraterangedate", errorMessage);
context.Attributes.Add("data-val-preliminaryraterangedate-rangedates",
JsonConvert.SerializeObject(new {MaxDateName = $"#{_maxDateName}", MinDateName = $"#{_minDateName}"}));
}
How can I get model object to get the properties values? This example is good only if model object contains primitive types. And cannot work with model object that contains complex type
You can directly get the property by model, but you need specify its type.
Below is a demo:
Model:
public class TimeModel
{
public string Name { get; set; }
public MyTime MyTime { get; set; }
}
public class MyTime
{
[Ranges]
public DateTime RangeDatetime { get; set; }
}
RangesAttribute:
public class RangesAttribute : ValidationAttribute, IClientModelValidator
{
public void AddValidation(ClientModelValidationContext context)
{
var viewContext = context.ActionContext as ViewContext;
var modelType = context.ModelMetadata.ContainerType;
var model = (TimeModel)viewContext?.ViewData.Model;
var name = model.Name;
var rangeDatetime = model.MyTime.RangeDatetime
//...
}
}
Controller:
public IActionResult Index()
{
TimeModel model = new TimeModel
{
Name = "AAAAA",
MyTime = new MyTime { RangeDatetime = DateTime.Now}
};
return View(model);
}
Result:
Update:
public void AddValidation(ClientModelValidationContext context)
{
var viewContext = context.ActionContext as ViewContext;
var model = viewContext.ViewData.Model;
Dictionary<string, string> myDict = new Dictionary<string, string>();
Type type = model.GetType();
foreach (PropertyInfo pi in type.GetProperties())
{
var subModel = pi.GetValue(model, null);
Type subtype = pi.GetValue(model, null).GetType();
if (!subtype.IsPrimitive && !subtype.Equals(typeof(string)))
{
var pii = subtype.GetProperties();
foreach (PropertyInfo item in pii)
{
myDict[item.Name] = item.GetValue(subModel, null)?.ToString();
}
}
else
{
myDict[pi.Name] = pi.GetValue(model, null)?.ToString();
}
}
}
var viewContext = context.ActionContext as ViewContext;
var modelType = context.ModelMetadata.ContainerType;
var instance = viewContext?.ViewData.Model;
var model = instance?.GetType().Name == modelType.Name
? instance
: instance?.GetType()?.GetProperties().First(x => x.PropertyType.Name == modelType.Name)
.GetValue(instance, null);
var maxDate = (DateTime?)modelType.GetProperty(_maxDateName)?.GetValue(model, null);
var minDate = (DateTime?)modelType.GetProperty(_minDateName)?.GetValue(model, null);
var errorMessage = string.Format(ErrorMessageString, minDate?.ToString("MM/dd/yyyy"), maxDate?.ToString("MM/dd/yyyy"));
context.Attributes.Add("data-val-preliminaryraterangedate", errorMessage);
context.Attributes.Add("data-val-preliminaryraterangedate-rangedates",
JsonConvert.SerializeObject(new {MaxDateName = $"#{_maxDateName}", MinDateName = $"#{_minDateName}"}));
You can get type that you need from context.ModelMetadata.ContainerType; and compare it with parent model property type

FindOneAndUpdateAsync Intermittently Returning Null

I am using MongoDB.Driver for .NET Core 3.1 and running into an issue were records are not being saved properly. They are intermittently coming back as null when calling FindOneAndUpdateAsync. I have a script that calls my below code 100 times. Out of those 100, 1-5 fail in the last method, SetChildFavoritesAsync. The results came back as null. Any suggestions on what I am doing wrong?
Example Calls
var id = 1;
var childName = "test";
var collectionEntry = await FindByIdOrCreateAsync(id);
collectionEntry.Children = new List<MyCollection.ChildClass>{
new MyCollection.ChildClass{
Name = childName,
Favorites = new List<MyCollection.ChildClass.Favorite>()
}
};
await FindByIdAndUpdateChildrenAsync(collectionEntry.Id, collectionEntry.Children);
var favorites = new List<MyCollection.ChildClass.Favorite>{
Name = "testFavorite"
};
var resultsOfSet = await SetChildFavoritesAsync(id, name, favorites)
//do stuff with resultsOfSet
Example Model
public class MyCollection
{
[MongoDB.Bson.Serialization.Attributes.BsonRepresentation(BsonType.ObjectId)]
[MongoDB.Bson.Serialization.Attributes.BsonId]
public string _Id { get; set; }
[MongoDB.Bson.Serialization.Attributes.BsonRequired]
public int Id { get; set; }
public List<ChildClass> Children { get; set; }
public class ChildClass
{
public string Name { get; set; }
public List<Favorite> Favorites { get; set; }
public class Favorite
{
public string Name { get; set; }
}
}
}
Example Methods
public async Task<MyCollection> FindByIdOrCreateAsync(int id)
{
var filter = Builders<MyCollection>.Filter.Eq(mc => mc.Id, id);
var update = Builders<MyCollection>.Update
.Set(mc => mc.Id, id)
.SetOnInsert(mc => mc.Children, new List<MyCollection.ChildClass>());
var options = new FindOneAndUpdateOptions<MyCollection> { ReturnDocument = ReturnDocument.After, IsUpsert = true };
return await _database.GetCollection<MyCollection>("MyCollectionName").FindOneAndUpdateAsync(filter, update, options);
}
public async Task<MyCollection> FindByIdAndUpdateChildrenAsync(int collectionId, List<MyCollection.ChildClass> children)
{
var filter = Builders<MyCollection>.Filter.Eq(mc => mc.Id, collectionId);
var update = Builders<MyCollection>.Update.Set(mc => mc.Children, children);
var options = new FindOneAndUpdateOptions<MyCollection> { ReturnDocument = ReturnDocument.After, IsUpsert = false };
return await _database.GetCollection<MyCollection>("MyCollectionName").FindOneAndUpdateAsync(filter, update, options);
}
public async Task<MyCollection> SetChildFavoritesAsync(int collectionId, string childName, List<MyCollection.ChildClass.Favorite> favorites)
{
var filter = Builders<MyCollection>.Filter.Eq(mc => mc.Id, collectionId);
filter &= Builders<MyCollection>.Filter.Eq("children.name", childName);
var update = Builders<MyCollection>.Update.Set("children.$.favorites", favorites);
var options = new FindOneAndUpdateOptions<MyCollection> { ReturnDocument = ReturnDocument.After };
var results = await _database.GetCollection<MyCollection>("MyCollectionName").FindOneAndUpdateAsync(filter, update, options);
if (results == null)
{
_log.Error($"Child Favorites didn't save: collectionId:{collectionId}, childName:{childName}");
}
else
{
_log.Debug($"Child Favorites: collectionId:{collectionId}, childName:{childName}, favorites:{Newtonsoft.Json.JsonConvert.SerializeObject(results)}");
}
return results;
}
Appears to be an issue with communication to the database. I added some retry logic, which solved the issue.

Model returns null when the site first loads

So, I recently found quite an issue with my site: when it first loads, a section of the website is missing. After some tests, I found that this line was sometimes false: #if (Model != null && Model.Any()). After a test using a single Modal == null, I found that yes, the issue is that it's sometimes null. Also, I found that the best way for me to reproduce the issue (no error messages) is to restart visual studio. CTRL + F5 does not make it be null. Any ideas why is that ?
Here's the Model and the part of cshtml:
public class BlogModel
{
public int Id { get; set; }
public bool AfficheAuteur { get; set; }
public string Alias { get; set; }
public string Sujet { get; set; }
public string Auteur { get; set; }
public string Photo { get; set; }
public int? Ordre { get; set; }
public PostModel Post { get; set; }
}
public class PostModel
{
public int Id { get; set; }
public string Alias { get; set; }
public string Nom { get; set; }
}
//.cshtml:
#model IList<Project.Models.Shared.BlogModel>
//...
#if (Model != null && Model.Any())
//...
Note that I'm using asp.net Core MVC with razor.
Edit:
public static IList<BlogModel> GetBlogs()
{
var _lock = new object();
var strKey = string.Format("Home-Blogs-{0}", Site.Id);
var blogs = (IList<BlogModel>)CacheManager.Get(strKey);
if (blogs == null)
{
lock (_lock)
{
blogs = (IList<BlogModel>)CacheManager.Get(strKey);
if (blogs == null)
{
using (var context = new DB())
{
context.Configuration.LazyLoadingEnabled = false;
var nIdSite = Site.Id;
var bl = (from b in context.Blog
where b.Actif &&
(b.IdsSite.Contains("," + nIdSite + ",")) &&
b.Posts.Any(y => y.Publier)
orderby b.Ordre
select new BlogModel()
{
Id = b.Id,
AfficheAuteur = b.AfficherAuteur,
Alias = b.Alias,
Sujet = b.Sujet,
Photo = b.Image,
Auteur = b.User.Profile.FirstName + " " + b.User.Profile.LastName,
Ordre = b.Ordre,
Post = (from p in context.BlogPost
where p.Publier &&
p.IdBlog == b.Id &&
p.DateAffichage <= DateTime.Now
orderby p.DateAffichage descending
select new PostModel()
{
Id = p.Id,
Alias = p.Alias,
Nom = p.Nom
}).FirstOrDefault()
}).ToList();
CacheManager.Insert(strKey, bl, null, 10800, Cache.NoSlidingExpiration, CacheItemPriority.High, null);
return blogs;
}
}
}
}
return blogs;
}
public ActionResult Index(GridSettings settings, string strQuery)
{
var model = new IndexBlogViewModel(settings, blogService, strQuery);
ViewBag.FilAriane.Add(new KeyValuePair<string, string>(Url.Action("Index", "Home"), "Accueil"));
ViewBag.FilAriane.Add(new KeyValuePair<string, string>("", "Blogs"));
return View(model);
}
[HttpGet]
public ActionResult Create()
{
var model = new BlogFormViewModel { Blog = new Entitie.Blog { IdSite = IdSite } };
var lstUser = new List<User>();
var cfUserProvider = new CFUserProvider();
foreach (var mu in cfUserProvider.GetAllUsers().Cast<MembershipUser>())
{
var r = new CFRoleProvider();
if (r.IsUserInRole(mu.UserName, "Bloggeur"))
{
var u = new User { Username = mu.UserName, Id = Convert.ToInt32(mu.ProviderUserKey) };
lstUser.Add(u);
}
}
model.User = lstUser.Select(x => new SelectListItem
{
Text = x.Username,
Value = x.Id.ToString()
});
model.Sites = siteService.GetAll(x => x.IdEntreprise == IdEntreprise)
.Select(x => new CheckBoxListItem
{
Id = x.Id,
Display = x.Nom,
IsChecked = false
}).ToList();
ViewBag.FilAriane.Add(new KeyValuePair<string, string>(Url.Action("Index", "Home"), "Accueil"));
ViewBag.FilAriane.Add(new KeyValuePair<string, string>("", "Blog"));
return View(model);
}
Found it... It was checking for null and if it was, was adding it to cache but still returning the non-updated variable. Simply had to update it before returning...
Added:
blogs = (IList<BlogModel>)CacheManager.Get(strKey);
before returning.

MVC3 Session State

I've recently been re-factoring my code to move from inproc to Session State. I've created a new class that I built from the start to be serializable. I'm currently getting the 'Unable to serialize the session state.' error. However, I am able to serialize the class using JsonConvert (newtonsoft).
Are methods not allowed or something?
This is what it looks like:
[Serializable()]
public class SessionStateObject
{
public int CurrentSessionId { get; set; }
public int CurrentAssessmentId { get; set; }
public int CurrentAssessmentElementId { get; set; }
public int CurrentUserId { get; set; }
public Dictionary<string, int> AssessmentItemsIds { get; set; }
public Dictionary<string, int> SessionResponseIds { get; set; }
public List<string> AdministeredItemOrderByName;
public string LastVisitedItem;
public int? TotalAssessmentCurrentItemOrder;
public RenderablePersistanceObject RenderablePersistance;
#region formula engine section variables
public string BranchingResult { get; set; }
public string ContentOutput { get; set; }
public int CurrentItemId { get; set; }
public int VirtualWorkingItemId { get; set; }
public bool isCloneItem { get; set; }
public bool wasPreFormulaRun;
public bool wasContentOutput;
public bool wasPrefillReached;
public bool isVirtual;
public List<string> FormulaStack { get; set; }
public List<string> ItemNameTokens { get; set; }
public string serializedJSContext { get; set; }
public string CloneSourceItem { get; set; }
public int itemsAbletoFastForwardThrough { get; set; }
#endregion
private Dictionary<int, int> itemIdByMultiGroupId; //key is itemId, val is groupId
private Dictionary<int, List<int>> MultiGroupIdByItemIds; //key is groupId, val is itemId
public SessionStateObject()
{
RenderablePersistance = new RenderablePersistanceObject();
AssessmentItemsIds = new Dictionary<string, int>();
SessionResponseIds = new Dictionary<string, int>();
AdministeredItemOrderByName = new List<string>();
FormulaStack = new List<string>();
ItemNameTokens = new List<string>();
itemIdByMultiGroupId = new Dictionary<int, int>();
MultiGroupIdByItemIds = new Dictionary<int, List<int>>();
}
public void initMultiItemGroups(Assessment assessment, NetScidDbContainer dbContext)
{
List<MultiItem> assessmentMultiItems = (from multi in dbContext.MultiItems
where multi.AssessmentId == assessment.Id
select multi).ToList();
List<int> uniqueGroupIds = new List<int>();
foreach (MultiItem mItem in assessmentMultiItems)
{
itemIdByMultiGroupId.Add(mItem.ItemId, mItem.GroupId);
if (!uniqueGroupIds.Contains(mItem.GroupId))
{
uniqueGroupIds.Add(mItem.GroupId);
}
}
foreach (int groupId in uniqueGroupIds)
{
List<int> ItemIds = (from itemGroup in assessmentMultiItems
where itemGroup.GroupId == groupId
orderby itemGroup.Id ascending
select itemGroup.ItemId).ToList();
MultiGroupIdByItemIds.Add(groupId, ItemIds);
}
}
public List<int> GetItemIdsFromSingleItemId(int itemId)
{
List<int> foundItemIDs = new List<int>();
int foundGroupId = -1;
if (this.itemIdByMultiGroupId.ContainsKey(itemId))
{
foundGroupId = this.itemIdByMultiGroupId[itemId];
}
if (this.MultiGroupIdByItemIds.ContainsKey(foundGroupId))
{
foundItemIDs = this.MultiGroupIdByItemIds[foundGroupId];
}
return foundItemIDs;
}
public void nullifyRenderable()
{
this.RenderablePersistance = null;
}
public void PersistRenderable(IRenderable renderable)
{
this.RenderablePersistance = new RenderablePersistanceObject();
if (renderable is MultiItemRenderable)
{
//get list of item IDs from the multi-item lookup
this.RenderablePersistance.isMultiItem = true;
this.RenderablePersistance.primaryItemId = ((Item)((MultiItemRenderable)renderable).IndexedItems.Last()).Id;
}
else //regular renderable
{
this.RenderablePersistance.isMultiItem = false;
this.RenderablePersistance.primaryItemId = ((Item)renderable).Id;
}
}
public AssessmentRuntime StartAdministrativeSession(NetScidDbContainer dataContext, Assessment assessment, User currentUser, string pid = "1")
{
AssessmentRuntime newRuntime = new AssessmentRuntime(this, dataContext);
Session newSession = new Session();
assessment.PrepElements();
PermissionEntity rootPE = new PermissionEntity();
if (currentUser != null)
{
rootPE = PermissionEntityHelper.GetRootPermissionEnity(dataContext, currentUser);
}
else
{
rootPE = (from adminpe in dataContext.PermissionEntities
where adminpe.Name == "TelesageAdmin"
select adminpe
).FirstOrDefault();
}
newSession.Participant = (from pids in dataContext.ParticipantIdAliasLookups
where pid == pids.AliasId && pids.RootPermissionEntity.Id == rootPE.Id
select pids.Participant).FirstOrDefault();
if (newSession.Participant == null)
{
Participant newParticipant = new Participant();
ParticipantIdAliasLookup newPidAlias = new ParticipantIdAliasLookup();
newParticipant.ParticipantDataJSON = "";
newPidAlias.AliasId = pid;
newPidAlias.RootPermissionEntity = rootPE;
newParticipant.AliasLookup = newPidAlias;
newParticipant.PermissionEntities.Add(currentUser.PermissionEntity);
newParticipant.PermissionEntities.Add(rootPE);
newSession.Participant = newParticipant;
dataContext.Participants.AddObject(newParticipant);
dataContext.ParticipantIdAliasLookups.AddObject(newPidAlias);
}
newSession.Assessment = assessment;
newSession.User = currentUser;
newSession.StartTime = DateTime.Now;
newSession.PermissionEntity = currentUser.PermissionEntity;
newSession.SetSessionData("engineversion", typeof(SmartQWeb.MvcApplication).Assembly.GetName().Version.ToString());
newSession.SetSessionData("assessmentname", newSession.Assessment.Name);
newSession.SetSessionData("assessmentversion", newSession.Assessment.Version);
newSession.SetSessionData("computername", Environment.MachineName);
newSession.SetSessionData("username", currentUser.Name);
dataContext.Sessions.AddObject(newSession);
newSession.SetSessionData("dxdata", JsonConvert.SerializeObject(newRuntime.RenderedDiagnoses));
newRuntime.formulaEngine = new FixedLengthFormulaEngine(newRuntime);
SessionLog newSessionLog = new SessionLog();
dataContext.SessionLogs.AddObject(newSessionLog);
newSession.SessionLog = newSessionLog;
dataContext.SaveChanges();
initMultiItemGroups(assessment, dataContext);
this.CurrentSessionId = newSession.Id;
this.CurrentUserId = currentUser.Id;
this.CurrentAssessmentId = assessment.Id;
newRuntime.Context = new RuntimeContext(this, dataContext);
this.GetAssessmentItems(assessment); //to populate the items dict
newRuntime.formulaEngine.InitializeContext(this.AssessmentItemsIds.Keys.ToList());
newRuntime.RenderedDiagnoses = new RenderedDiagnosisModel(newRuntime.Context.AdministeredItemOrderByName);
newRuntime.Context.Logger.WriteLog("Session started with assessment: " + newRuntime.Context.Assessment.Name + " with version: " + newRuntime.Context.Assessment.Version);
newRuntime.Context.Logger.WriteLog("Session started by user: " + newRuntime.Context.CurrentUser.Name + "for participant ID: " + newSession.ParticipantId);
return newRuntime;
}
//start from a previous existing session
public AssessmentRuntime StartAdministrativeSession(NetScidDbContainer dataContext, Assessment assessment, Session previousSession, User currentUser, string pid = "", string resumefromlatest = "false")
{
AssessmentRuntime newRuntime = new AssessmentRuntime(this, dataContext);
Session newSession = new Session();
Assessment sessionAssessment = assessment;
newSession.ParticipantId = previousSession.ParticipantId;
//THE OTHER ENTITIES BESIDES THE SESSION NEED TO BE DETATCHED AND RE-ATTACHED (BY BEING ADDED TO THE NEW SESSION)
assessment.PrepElements();
newRuntime.RenderedDiagnoses = new RenderedDiagnosisModel(newRuntime.Context.AdministeredItemOrderByName);
List<Response> prevresponses = previousSession.Responses.ToList();
if (sessionAssessment == assessment)
{
foreach (Response prevresponse in prevresponses)
{
newRuntime.Context.CachedAssessmentResponses.Add(prevresponse.Item.ItemName, prevresponse);
dataContext.Detach(prevresponse);
newSession.Responses.Add(prevresponse);
}
}
else
{
//the sessionAssessment is now the more up-to-date one so the responses pulled will have to be mapped, not just detatched and copied
foreach (Response prevresponse in prevresponses)
{
Dictionary<string, FixedLengthItem> newAssessmentItemNames = AssessmentHelper.GetAssessmentItems(sessionAssessment);
if (!newAssessmentItemNames.ContainsKey(prevresponse.Item.ItemName))
continue;
Response newResponse = new Response
{
NumericValue = prevresponse.NumericValue,
Item = newAssessmentItemNames[prevresponse.Item.ItemName],
ItemName = prevresponse.Item.ItemName,
AdministeredOrder = -1,
Value = prevresponse.Value
};
newRuntime.Context.CachedAssessmentResponses.Add(newResponse.Item.ItemName, newResponse);
newSession.Responses.Add(newResponse);
}
}
newSession.SessionDataJSON = previousSession.SessionDataJSON;
//DxData
newRuntime.RenderedDiagnoses =
JsonConvert.DeserializeObject<RenderedDiagnosisModel>(newSession.GetSessionData("dxdata"));
//inc session is =2 when the the session has been resumed by
previousSession.IncSession = 2;
newSession.SetSessionData("previoussession", previousSession.Id.ToString());
newSession.Participant = previousSession.Participant;
newSession.Assessment = sessionAssessment;
newSession.User = currentUser;
newSession.PermissionEntity = currentUser.PermissionEntity;
newSession.StartTime = DateTime.Now;
dataContext.Sessions.AddObject(newSession);
dataContext.SaveChanges();
newRuntime.formulaEngine = new FixedLengthFormulaEngine(newRuntime);
initMultiItemGroups(assessment, dataContext);
newSession.SetSessionData("continuedsession", newSession.Id.ToString());
this.CurrentSessionId = newSession.Id;
this.CurrentUserId = currentUser.Id;
this.CurrentAssessmentId = assessment.Id;
this.GetAssessmentItems(assessment); //to populate the items dict
this.SetUpPreviousResponses(newSession); //populates SSO responses
newRuntime.Context = new RuntimeContext(this, dataContext);
if (newRuntime.RenderedDiagnoses != null)
newRuntime.RenderedDiagnoses.reInitAdminOrder(newRuntime.Context.AdministeredItemOrderByName);
newRuntime.formulaEngine.InitializeContext(this.AssessmentItemsIds.Keys.ToList());
return newRuntime;
}
//start from the SSO
public AssessmentRuntime ResumeSessionFromState(NetScidDbContainer dataContext)
{
AssessmentRuntime newRuntime = new AssessmentRuntime(this, dataContext);
newRuntime.formulaEngine = new FixedLengthFormulaEngine(newRuntime);
newRuntime.formulaEngine.InitializeSerializedContext(serializedJSContext);
newRuntime.Context = new RuntimeContext(this, dataContext);
if (this.CurrentAssessmentElementId != 0)
{
newRuntime.CurrentAssessmentElement = (from ae in dataContext.AssessmentElements
where ae.Id == this.CurrentAssessmentElementId
select ae).FirstOrDefault();
newRuntime.CurrentAssessmentElement.GetNewRuntime(newRuntime.Context);
}
return newRuntime;
}
private void GetAssessmentItems(Assessment assessment)
{
var fixedLengthElements = (from elements in assessment.AssessmentElements
where elements is FixedLengthBlock
select elements);
foreach (FixedLengthBlock elemblock in fixedLengthElements)
{
foreach (FixedLengthItem item in elemblock.ItemBank.Items)
{
item.aeRef = elemblock;
AssessmentItemsIds.Add(item.ItemName, item.Id);
}
}
}
private void SetUpPreviousResponses(Session newSession)
{
//put response IDs by itemname into this dictionary
SessionResponseIds = (from response in newSession.Responses
select response).ToDictionary(key => key.ItemName, value => value.Id);
}
}
And the RenderablePersistanceObject looks like this:
public class RenderablePersistanceObject
{
public int primaryItemId;
public int MultiItemGroupId;
public bool isMultiItem;
}
You can't serialize a straight Dictionary like that. You can take a look at this MSDN article for suggestions on implementing. If you don't truly need a Dictionary, perhaps List> might work better?
As Erik pointed out, it was the lack of the adorner [Serializable()] on that other object that caused the problem. Adding it solved my issue.

Circular Reference Found. Property of class datatype inside class

public class childrens {
public ICollection<childrens> children { get; set; }
public data data { get; set; }
public string id { get; set; }
public string name { get; set; }
}
public static childrens GetJsonData()
{
childrens rootNode = new childrens();
rootNode.data = new data();
rootNode.id = "root";
rootNode.name = "Top Albums";
childrens objChildren547 = new childrens();
objChildren547.data = new data { playcount = 547, area = "547" };
objChildren547.id = "artist_A Perfect Circle";
objChildren547.name = "A Perfect Circle";
rootNode.children = new List<childrens>();
rootNode.children.Add(objChildren547);
childrens objChildren276 = new childrens();
objChildren276.data = new data { playcount = 276, artist = "A Perfect Circle", image = "http:\\/\\/userserve-ak.last.fm\\/serve\\/300x300\\/11403219.jpg", area = "276" };
objChildren276.id = "album-Thirteenth Step";
objChildren276.name = "Thirteenth Step";
objChildren547.children = new List<childrens>();
objChildren547.children.Add(objChildren276);
childrens objChildren271 = new childrens();
objChildren271.data = new data { playcount = 271, artist = "A Perfect Circle", image = "http:\\/\\/userserve-ak.last.fm\\/serve\\/300x300\\/11403219.jpg", area = "271" };
objChildren271.id = "album-Mer De Noms";
objChildren271.name = "Mer De Noms";
objChildren547.children.Add(objChildren271);
return rootNode;
}
[WebMethod]
public static HttpResponseMessage GetJsonData()
{
var data = jsondata.GetJsonData();
return new HttpResponseMessage { Content = new ObjectContent(typeof(childrens), data, new System.Net.Http.Formatting.JsonMediaTypeFormatter() { SerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, PreserveReferencesHandling = PreserveReferencesHandling.None, MaxDepth = 10 } }) };
//return data;
}
The above code gives me an error "Circular Reference Found". I used the property reference handling but it didn't work.
How can I achieve this using NewtonSoft.Json Library to serialize it.
Thanks in advance.
You need to configure the ReferenceLoopHandling option of the serialization settings to ReferenceLoopHandling.Serialize. You pass the options into the JsonConvert.SerializeObject method I believe.

Resources