MVC2 Multilevel navigation - asp.net-mvc

One question I have yet to find an answer on is this. How do I keep track of active Sitemap nodes on multiple levels?
For example :
node 1
node 2 "active"
Child node 1
Child node 2 "active"
node 3
How do I keep track of a childnode being active as well as the parent it belongs to being marked as active.
I know there is something called IsDescendant but I always get exceptions when using it due to null values.
Is there some screencast/tutorial on doing more advanced custom navigation in mvc.net(or asp.net for that matter). Most seem to deal with simple one level navigation.
I would prefer examples in C# if possible, thank you.

Ok ,,, I've suffered from the same issue and I came up with a work around, check my answer in this question :
Hierarchical menu in view based on parent child class
I've been meaning to come up with a more generic elegant way of doing it since I've faced the problem but I've been busy ever since. I'm hoping I'll find some time in the next weeks to come up with something ,,,
Note : for simplicity in my solution in the above question in the methods DisplayMenu and ConvertToItem particularity, I've removed the parts where it should check for the currentMenuID and the currentMenuItemID fields and add the current css class to the li element (or active class in your case).
Since this is all what's your question is about, I've provided the full methods below.
public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
{
string classOfCurrentMenu;
String result = "<ul id='main-nav'>\n";
foreach(Menu menu in navigationMenu.Menus)
{
classOfCurrentMenu = "";
if (menu.ID == navigationMenu.currentMenuID)
{
classOfCurrentMenu = "current";
}
result += "<li>\n";
result += string.Format("<a href='#' class='{0}'> {1} </a>\n", helper.AttributeEncode(classOfCurrentMenu),helper.AttributeEncode(menu.Name));
result += "<ul>\n";
foreach(MenuItem item in menu.MenuItems)
{
result += NavigationHelper.ConvertToItem(helper, item, navigationMenu.currentMenuID, navigationMenu.currentMenuItemID);
}
result += "</ul>\n";
result += "</li>\n";
}
result += "</ul>\n";
return result;
}
private static string ConvertToItem(this HtmlHelper helper,MenuItem item, int currentMenuID, int currentMenuItemID)
{
if (item.Show)
{
string classOfCurrentItem = "";
if (item.ID == currentMenuItemID && item.MenuID == currentMenuID)
classOfCurrentItem = "current";
return string.Format("<li><a href='{0}' class='{1}'>{2}</a></li>\n", helper.AttributeEncode(item.Link), helper.AttributeEncode(classOfCurrentItem), helper.AttributeEncode(item.Label));
}
else { return ""; }
}
I don't consider this as a perfect solution to the problem, I hate writing HTML in C# code, I will try my best to come up with a more generic (multi level) cleaner solution for the problem, and of course make use of the TagBuilder class in the framework.

Related

Xtext CustomScopeProvider Problems with adding candidates

I am working on an xtext Project where I have to customize the Scope Provider. I need to add up some possible candidates for the scope. The first part (getServiceInputs()) works fine but for the second one (addAll(sub.GetSubRecipeParameters()) not. Debugging showed that they get removed from its original source (sub) and can therefore not be retrieved again. When simply commenting out the addAll line the SubRecipeParameters remain in sub. Really dont know how to solve that, tried already some work arounds. Anyone with an Idea?
public class AutomationServiceDslScopeProvider extends AbstractAutomationServiceDslScopeProvider {
#Override
public IScope getScope(EObject context, EReference reference) {
if (context instanceof ServiceInvocationParameter
&& reference == AutomationServiceDslPackage.Literals.LITERAL) {
ServiceInvocation serviceCall = (ServiceInvocation) invocationParameter.eContainer();
ServiceDefinition calledService = serviceCall.getService();
List<ServiceParameterDefinition> candidates= calledService.getServiceInputs();
final EObject rootContainer = EcoreUtil.getRootContainer(context);
List<SubRecipeDefinition> subs = EcoreUtil2.getAllContentsOfType(rootContainer, SubRecipeDefinition.class);
for(SubRecipeDefinition sub:subs) {
for(RecipeStep step:sub.getRecipeSteps()) {
if(step.getName()==serviceCall.getName()) {
candidates.addAll(sub.getSubRecipeParameters());
}
}
}
return Scopes.scopeFor(candidates);
Thanks for any help!!
This is normal EMF behaviour if you move elements from one EList to another one. The solution is to create a new list e.g. new ArrayList<>() and also add the inputs there
List<ServiceParameterDefinition> candidates = new ArrayList<>();
candidates.addAll(calledService.getServiceInputs());

Avoid to show Null or specific values to razor view engine

I am working on asp.net mvc3 web application using MS Sql server 2008 express rc2. In my app I have two different brands in DB and one of them have few Null or 'unknown' values (e.g. 'unknown' is added to DB instead of Null). My question is how to pass only non null values to View Engine instead of using If/Else statements in View?
in controller:
var model = _data.GetViewModel(query);
if (model != null)
{
return View(model);
}
else
return View("Error");
in ViewModel;
public int Id { get; set; }
public string Query { get; set; }
public string Brand { get; set; }
public string Family { get; set; }
public string Type { get; set; }
in Model:
public ViewModel GetViewModel(string query)
{
var data = _comp.Get(p => p.Query == query);
if (data == null) return null;
return new ViewModel
{
Id = data.id,
Brand = data.brand,
Family = data.family,
Type = data.type
};
}
in View (I am currently using If statement):
#if (Model.Brand != null)
{
<span class="brand">#Model.Brand</span>
}
#if (Model.Family != null)
{
<span class="family">#Model.Family</span>
}
#if (Model.Type != null)
{
<span class="type">#Model.Type</span>
}
Note: I want to avoid If statement because there are too many values in the Database of each brand, and many of the them are Null, So I don't want to generate Html for those Null values. I am using If/Else statement like above code, and for checking too many values in View using If, it costs Memory on server and processor, and it also slow down server response time.
I want to have an alternative method to do this. Should I use Partial views or anything else?
Please Please help me to solve this, Your help is very appreciated.
Thanks and Regards.
First, some background/context, then my suggestion.
(By the way, this all applies to any version of ASP.NET MVC or ASP.NET NancyFX (yes, there's another option out there!!), etc)
Context / Background
To solve this, people generally fall into two types of categories:
Just get data and let the View decide what to show (common one, not the proper way IMO).
The Controller should handle all the heavy lifting and give the view the exact answer (proper way, IMO).
The first way is quick and dirty. Sure it works, but it puts too much logic into the view. Views are not supposed to do any logic at all (exception: for loops, and maybe the odd if/else, maybe). The main reason for this is testing. Yep, that dirty word which people hate and think it's for hippies only. Or .. I don't have the time to test.. so I manually test, etc.. If you put any business logic into a view, you cannot test that.
The second way might seem a bit slower at first, but that's like anything - the more you practice, the faster you go. This is (IMO) the preferred method of doing things because you can test the controller. The controller should create a view model which will have -the exact- results that the view needs. Not extra. For example, imagine you want to return a list of Brands to the display/view. Most people do (the equivalent of) Get-all-brands into a list, and send that list to the view, even though 80% of those properties are -not- going to be used by that view! Even if ONE property is not going to be used by that view, do not retrieve it nor send it to the view!
So - TL;DR; do all the heavy lifting in the controller. The View is dumb. Just dump the exact view model data, to the view.
Solution to your problem
Ok, so let's roll with idea #2 and get all this stuff happening in the controller.
// Grab the results.
// ASSUMPTION: It is only returning the -exact- data I need. No more, no less.
var results = _data.GetViewModel(query);
if (model == null)
{
// Project the results into a perfectly tight & svelte view model
// 100% specific for this view.
var viewModel = results.
Select(x => new ViewModel
{
Id = x.Id,
Brand = string.IsNullOrEmpty(x.Brand)
? string.Empty
: x.Brand,
Family = string.IsNullOrEmpty(x.Family)
? string.Empty
: x.Family,
Type = string.IsNullOrEmpty(x.Type)
? string.Empty
: x.Type,
}).ToList();
return viewModel;
Testing this..
[Fact]
public void GivenSomeBrands_Index_ReturnsAViewModel()
{
// Arrange.
// NOTE: Our fake repostitory has some fake data. In it ..
// Id: 1, Brand: Gucci.
// Id: 22, Brand: null.
var controller = new BrandController(SomeFakeRepositoryThingy);
// Act.
var result = controller.Index(); // This calls that controller code, above.
// Assert.
Assert.IsNotNull(result); // Controller returned some result.
Assert.IsNotNull(result.Model); // We have some model data.
var model = result.Model as IList<ViewModel>(); // Cast the Model value.
Assert.NotNull(model); // We have a strongly typed view model.
// We check the first brand value.
Assert.Equal("Gucci", model.First().Brand);
// We know this item has a null Brand,
Assert.Equal(string.Empty, model[21].Brand); but the ViewModel converted it.
}
You could write a custom HTML helper:
public static string MyHelper<V>(this HtmlHelper helper, V value, string css)
{
if (value == null)
return "";
return String.Format("<span class='{0}'>{1}</span>", value, css);
}
Then in your view:
#Html.MyHelper(Model.Brand, "brand");
#Html.MyHelper(Model.Family, "family");
#Html.MyHelper(Model.Type, "type");

Asp.net MVC Model for view and Layout

I've been trying to find a good way to handle the Models of our Asp.net MVC websites when having common properties for all the pages. These properties are to be displayed in the Layout (Master Page). I'm using a "BaseModel" class that holds those properties and my Layout use this BaseModel as its model.
Every other model inherits from that BaseModel and each has specific properties relative to the view it represents. As you might have guessed, my Models are actually View Models even if that's not quite relevant here.
I have tried different ways to initialize the BaseModel values
By "hand" in every view
Having a base controller that has an Initialize virtual method to do it (so specific controller can implement specific common behavior for exemple)
Having a base controlelr that override OnActionExecuting to call the Initialize method
Using a helper class to do it outside of the controller
Using a Model Factory
But none of those really appeal to me:
Seems obvious to me, but DRY is one reason enough to justify that (actually I never tried that solution at all, I'm just putting it to be able to loop on that point in the last point).
I don't like that one because it means that whenever a new Controller is added, you need to know that it has to inherit from the BaseController and that you need to call the Initialize method, not to mention that if your controller has overriden the base one, to call the base anyway to maintain the values.
see next point
and 3. are a variation on the same topic but that doesn't really help with the issues of the second solution.
My favorite so far, but now I have to pass a few more variables to set those values. I like it for the inversion of dependence. But then if I want to provide values from the session, I need to pass them explicitly for exemple, then I'm back to square one as I have to provide them by hand (being references or through an interface of any kind)
Of course, (almost) all of those solutions work, but I'm looking for a better way to do it.
While typing this question, I found maybe a new path, the builder pattern that might also do, but implementations can become quickly a burden too, as we can have dozens of views and controllers.
I'll gladly take any serious recommandation/hint/advice/patterns/suggestion !
Update
Thanks to #EBarr I came up with another solution, using an ActionFilterAttribute (not production code, did it in 5 minutes):
public class ModelAttribute : ActionFilterAttribute
{
public Type ModelType { get; private set; }
public ModelAttribute(string typeName) : this(Type.GetType(typeName)) { }
public ModelAttribute(Type modelType)
{
if(modelType == null) { throw new ArgumentNullException("modelType"); }
ModelType = modelType;
if (!typeof(BaseModel).IsAssignableFrom(ModelType))
{
throw new ArgumentException("model type should inherit BaseModel");
}
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var model = ModelFactory.GetModel(ModelType);
var foo = filterContext.RequestContext.HttpContext.Session["foo"] as Foo;
model.Foo = foo;
model.Bar = somevalue;
filterContext.Controller.TempData["model"] = model;
}
}
Calling it is then really simple:
[Model(typeof(HomeModel))]
public ActionResult Index()
{
var homeModel = TempData["model"] as HomeModel;
// Add View Specific stuff
return View(homeModel);
}
And it gives me the best of every world. The only drawback is to find a proper way to passe the model back to the action.
Here it's done using the TempData object, but I also consider updating the model that one can find in the ActionParameters.
I'm still taking any serious recommandation/hint/advice/patterns/suggestion for that, or the previous points.
I went through almost exactly the same process as I dove into MVC. And you're right, none of the solutions feel that great.
In the end I used a series of base models. For various reasons I had a few different types of base models, but the logic should apply to a single base type. The majority of my view models then inherited from one of the bases. Then, depending on need/timing i fill the base portion of the model in ActionExecuting or OnActionExecuted.
A snippet of my code that should make the process clear:
if (filterContext.ActionParameters.ContainsKey("model")) {
var tempModel = (System.Object)filterContext.ActionParameters["model"];
if (typeof(BaseModel_SuperLight).IsAssignableFrom(tempModel.GetType())) {
//do stuff required by light weight model
}
if (typeof(BaseModel_RegularWeight).IsAssignableFrom(tempModel.GetType())) {
//do more costly stuff for regular weight model here
}
}
In the end my pattern didn't feel too satisfying. It was, however, practical, flexible and easy to implement varying levels of inheritance. I was also able to inject pre or post controller execution, which mattered a lot in my case. Hope this helps.
The idea that gave me #EBarr to use an action filter was actually working but felt wrong in the end, because there was no clean way to retrieve the model without passing through a viewbag, or the httpcontext items, or something alike. Also, it made mandatory to decorate every action with its model. It also made the postback more difficult to handle. I still believe that this solution has merits and might be useful in some specific scenarios.
So I was back to square one and started looking more into that topic. I came to the following. First the problem has two aspects
Initializing the data for the views
Rendering the data
While looking for more idea, I realized that I was not looking at the problem from the right perspective. I was looking at it from a "Controller" POV, whereas the final client for the model is the view. I was also reminded that the Layout/Master page is not a view and should not have a model associated with it. That insight put me on what feels the right path for me. Because it meant that every "dynamic" part of the Layout should be handled outside of it. Of course, sections seems the perfect fit for that, because of their flexibility.
On the test solution I made, I had (only) 4 different sections, some mandatory, some not. The problem with sections, is that you need to add them on every page, which can quickly be a pain to update/modify. To solve that, I tried this:
public interface IViewModel
{
KeyValuePair<string, PartialViewData>[] Sections { get; }
}
public class PartialViewData
{
public string PartialViewName { get; set; }
public object PartialViewModel { get; set; }
public ViewDataDictionary ViewData { get; set; }
}
For exemple, my model for the view is this:
public class HomeViewModel : IViewModel
{
public Article[] Articles { get; set; } // Article is just a dummy class
public string QuickContactMessage { get; set; } // just here to try things
public HomeViewModel() { Articles = new Article[0]; }
private Dictionary<string, PartialViewData> _Sections = new Dictionary<string, PartialViewData>();
public KeyValuePair<string, PartialViewData>[] Sections
{
get { return _Sections.ToArray(); }
set { _Sections = value.ToDictionary(item => item.Key, item => item.Value); }
}
}
This get initialized in the action:
public ActionResult Index()
{
var hvm = ModelFactory.Get<HomeViewModel>(); // Does not much, basicaly a new HomeViewModel();
hvm.Sections = LayoutHelper.GetCommonSections().ToArray(); // more on this just after
hvm.Articles = ArticlesProvider.GetArticles(); // ArticlesProvider could support DI
return View(hvm);
}
LayoutHelper is a property on the controller (which could be DI'ed if needed):
public class DefaultLayoutHelper
{
private Controller Controller;
public DefaultLayoutHelper(Controller controller) { Controller = controller; }
public Dictionary<string, PartialViewData> GetCommonSections(QuickContactModel quickContactModel = null)
{
var sections = new Dictionary<string, PartialViewData>();
// those calls were made in methods in the solution, I removed it to reduce the length of the answer
sections.Add("header",
Controller.UserLoggedIn() // simple extension that check if there is a user logged in
? new PartialViewData { PartialViewName = "HeaderLoggedIn", PartialViewModel = new HeaderLoggedInViewModel { Username = "Bishop" } }
: new PartialViewData { PartialViewName = "HeaderNotLoggedIn", PartialViewModel = new HeaderLoggedOutViewModel() });
sections.Add("quotes", new PartialViewData { PartialViewName = "Quotes" });
sections.Add("quickcontact", new PartialViewData { PartialViewName = "QuickContactForm", PartialViewModel = model ?? new QuickContactModel() });
return sections;
}
}
And in the views (.cshtml):
#section quotes { #{ Html.RenderPartial(Model.Sections.FirstOrDefault(s => s.Key == "quotes").Value); } }
#section login { #{ Html.RenderPartial(Model.Sections.FirstOrDefault(s => s.Key == "header").Value); } }
#section footer { #{ Html.RenderPartial(Model.Sections.FirstOrDefault(s => s.Key == "footer").Value); } }
The actual solution has more code, I tried to simplify to just get the idea here. It's still a bit raw and need polishing/error handling, but with that I can define in my action, what the sections will be, what model they will use and so on. It can be easily tested and setting up DI should not be an issue.
I still have to duplicate the #section lines in every view, which seems a bit painful (especialy because we can't put the sections in a partial view).
I'm looking into the templated razor delegates to see if that could not replace the sections.

pass parameter to repository while maintaining separation of concerns

I'm new to mvc and this whole way of programming is pretty unfamiliar for me, so be gentle ...
I have in my article repository:
public IQueryable<Article> GetArticles(int? category, int? position)
{
return from a in dc.Articles
where a.LanguageIndex == lang && a.CategoryIndex == category && a.ArticlePosition == position
select a;
}
How can I pass the parameters category and position from the interface while maitaining separation of concerns ?
I thought about :
public interface IArticleRepository
{
IQueryable<Article> GetArticles(Article a);
}
and passing the parameters along with the Article object, but this means I would have to pass the category and position in the controller.
Am I in the right direction here?
Not sure how this relates to separation of concerns. I can see where it might seem the abstraction is leaky; is it your concern that it seems users must know a little too much about how the repository holds your Articles?
Until someone comes up with a performant method of separating implementation from models, storage abstractions will always be leaky. You can beat yourself up over it or just do your best and deal.
Your second method is, IMHO, worse than the first. You still have to stipulate the category and position in your Article, so you still have the leak in addition to a weird API that confuses parameters with entities.
I'd definitely go with the first version over the second. If I were to do anything, I would refactor to make CategoryIndex and ArticlePosition entities (Category and Position tables linked to the Article table). You could then refactor your API to the more appealing:
var cat = CategoryRepository.GetCategory("foo");
var pos = PositionRepository.GetPosition("bar");
var article = ArticleRepository.GetArticle(cat, pos);
Is this any better than what you already have? Probably not.
Fist I would separate out the basic query:
public IQueryable<Article> GetArticles()
{
return from a in dc.Articles select a;
}
public IQueryable<Article> GetArticles(int? category, int? position)
{
return GetArticles ().Where (a => a.LanguageIndex == category && a.CategoryIndex == position).AsQueryable ();
}
Now if you want to move the specific query filter out of your repository you can move it to an extension method:
public static IQueryable<Article> WithCategory(this IQueryable<Article> articles, int? category, int? position)
{
return articles.Where (a => a.LanguageIndex == category && a.CategoryIndex == position).AsQueryable ();
}

Json and Circular Reference Exception

I have an object which has a circular reference to another object. Given the relationship between these objects this is the right design.
To Illustrate
Machine => Customer => Machine
As is expected I run into an issue when I try to use Json to serialize a machine or customer object. What I am unsure of is how to resolve this issue as I don't want to break the relationship between the Machine and Customer objects. What are the options for resolving this issue?
Edit
Presently I am using Json method provided by the Controller base class. So the serialization I am doing is as basic as:
Json(machineForm);
Update:
Do not try to use NonSerializedAttribute, as the JavaScriptSerializer apparently ignores it.
Instead, use the ScriptIgnoreAttribute in System.Web.Script.Serialization.
public class Machine
{
public string Customer { get; set; }
// Other members
// ...
}
public class Customer
{
[ScriptIgnore]
public Machine Machine { get; set; } // Parent reference?
// Other members
// ...
}
This way, when you toss a Machine into the Json method, it will traverse the relationship from Machine to Customer but will not try to go back from Customer to Machine.
The relationship is still there for your code to do as it pleases with, but the JavaScriptSerializer (used by the Json method) will ignore it.
I'm answering this despite its age because it is the 3rd result (currently) from Google for "json.encode circular reference" and although I don't agree with the answers (completely) above, in that using the ScriptIgnoreAttribute assumes that you won't anywhere in your code want to traverse the relationship in the other direction for some JSON. I don't believe in locking down your model because of one use case.
It did inspire me to use this simple solution.
Since you're working in a View in MVC, you have the Model and you want to simply assign the Model to the ViewData.Model within your controller, go ahead and use a LINQ query within your View to flatten the data nicely removing the offending circular reference for the particular JSON you want like this:
var jsonMachines = from m in machineForm
select new { m.X, m.Y, // other Machine properties you desire
Customer = new { m.Customer.Id, m.Customer.Name, // other Customer properties you desire
}};
return Json(jsonMachines);
Or if the Machine -> Customer relationship is 1..* -> * then try:
var jsonMachines = from m in machineForm
select new { m.X, m.Y, // other machine properties you desire
Customers = new List<Customer>(
(from c in m.Customers
select new Customer()
{
Id = c.Id,
Name = c.Name,
// Other Customer properties you desire
}).Cast<Customer>())
};
return Json(jsonMachines);
Based on txl's answer you have to
disable lazy loading and proxy creation and you can use the normal methods to get your data.
Example:
//Retrieve Items with Json:
public JsonResult Search(string id = "")
{
db.Configuration.LazyLoadingEnabled = false;
db.Configuration.ProxyCreationEnabled = false;
var res = db.Table.Where(a => a.Name.Contains(id)).Take(8);
return Json(res, JsonRequestBehavior.AllowGet);
}
Use to have the same problem. I have created a simple extension method, that "flattens" L2E objects into an IDictionary. An IDictionary is serialized correctly by the JavaScriptSerializer. The resulting Json is the same as directly serializing the object.
Since I limit the level of serialization, circular references are avoided. It also will not include 1->n linked tables (Entitysets).
private static IDictionary<string, object> JsonFlatten(object data, int maxLevel, int currLevel) {
var result = new Dictionary<string, object>();
var myType = data.GetType();
var myAssembly = myType.Assembly;
var props = myType.GetProperties();
foreach (var prop in props) {
// Remove EntityKey etc.
if (prop.Name.StartsWith("Entity")) {
continue;
}
if (prop.Name.EndsWith("Reference")) {
continue;
}
// Do not include lookups to linked tables
Type typeOfProp = prop.PropertyType;
if (typeOfProp.Name.StartsWith("EntityCollection")) {
continue;
}
// If the type is from my assembly == custom type
// include it, but flattened
if (typeOfProp.Assembly == myAssembly) {
if (currLevel < maxLevel) {
result.Add(prop.Name, JsonFlatten(prop.GetValue(data, null), maxLevel, currLevel + 1));
}
} else {
result.Add(prop.Name, prop.GetValue(data, null));
}
}
return result;
}
public static IDictionary<string, object> JsonFlatten(this Controller controller, object data, int maxLevel = 2) {
return JsonFlatten(data, maxLevel, 1);
}
My Action method looks like this:
public JsonResult AsJson(int id) {
var data = Find(id);
var result = this.JsonFlatten(data);
return Json(result, JsonRequestBehavior.AllowGet);
}
In the Entity Framework version 4, there is an option available: ObjectContextOptions.LazyLoadingEnabled
Setting it to false should avoid the 'circular reference' issue. However, you will have to explicitly load the navigation properties that you want to include.
see: http://msdn.microsoft.com/en-us/library/bb896272.aspx
Since, to my knowledge, you cannot serialize object references, but only copies you could try employing a bit of a dirty hack that goes something like this:
Customer should serialize its Machine reference as the machine's id
When you deserialize the json code you can then run a simple function on top of it that transforms those id's into proper references.
You need to decide which is the "root" object. Say the machine is the root, then the customer is a sub-object of machine. When you serialise machine, it will serialise the customer as a sub-object in the JSON, and when the customer is serialised, it will NOT serialise it's back-reference to the machine. When your code deserialises the machine, it will deserialise the machine's customer sub-object and reinstate the back-reference from the customer to the machine.
Most serialisation libraries provide some kind of hook to modify how deserialisation is performed for each class. You'd need to use that hook to modify deserialisation for the machine class to reinstate the backreference in the machine's customer. Exactly what that hook is depends on the JSON library you are using.
I've had the same problem this week as well, and could not use anonymous types because I needed to implement an interface asking for a List<MyType>. After making a diagram showing all relationships with navigability, I found out that MyType had a bidirectional relationship with MyObject which caused this circular reference, since they both saved each other.
After deciding that MyObject did not really need to know MyType, and thereby making it a unidirectional relationship this problem was solved.
What I have done is a bit radical, but I don't need the property, which makes the nasty circular-reference-causing error, so I have set it to null before serializing.
SessionTickets result = GetTicketsSession();
foreach(var r in result.Tickets)
{
r.TicketTypes = null; //those two were creating the problem
r.SelectedTicketType = null;
}
return Json(result);
If you really need your properties, you can create a viewmodel which does not hold circular references, but maybe keeps some Id of the important element, that you could use later for restoring the original value.

Resources