How do I use multiple schema GenerationProviders - json.net

We are using Json.Net Schema and require multiple generation providers.
However when we specify more than one generation provider it seems that only the last one in the list is used.
Here is an example where only ObjectNotNullableGenerationProvider is used and StringEnumGeneration is ignored.
Any example of example of multiple providers or help on why this is not working would be appreciated.
Example:
var generator = new JSchemaGenerator
{
SchemaReferenceHandling = SchemaReferenceHandling.None,
DefaultRequired = Required.Default,
};
generator.GenerationProviders.Add(new StringEnumGenerationProvider());
generator.GenerationProviders.Add(new ObjectNotNullableGenerationProvider());
var jsonSchema = generator.Generate(typeof(SchemaTest));

The GetSchema method on JSchemaGenerationProvider returns a new schema. Only the first matching schema generation provider is called and its schema is used.
What you could do is take the source code from StringEnumGenerationProvider (available here) and have you own version that either inherits from ObjectNotNullableGenerationProvider or reuses its logic internally.

Related

What do you call the method DI uses to populate a model?

Implementations of IHost like the generic host do dependency injection. You populate a services collection with helper methods like this
IConfigurationSection section;
section = config.GetSection("SectionName");
services.Configure<SectionModel>(section);
Inside the Configure helper method some magic creates an instance of SectionModel and populates it from the IConfigurationSection object.
What is that called? I need to do it in the absence of the DI and while I'm sure rummaging through Microsoft source code would probably yield answers I could rummage a lot faster armed with the name of the method that does it.
More than likely they just use reflection, but I'd prefer not to implement this myself and have potentially divergent behaviour.
According to documentation this is called Bind and is surfaced on IConfigurationSection.
First you create the config section and model objects, then you call Bind like so
var sectionModel = new SectionModel();
config.GetSection("SectionName").Bind(sectionModel);
#Nkosi comments
The same can be done using
var sectionModel = config.GetSection("SectionName").Get<SectionModel>();
This is a more elegant expression of the same solution using generics.

Something akin to "Sparse Fieldsets" in .NET

I'm trying to find the vocabulary to describe what I want and if it exists.
I have a table that shows a few data points from large objects. Loading the entire objects just for the table is very slow. Is there a way to only pass to the front the few properties I want without having to define a new object?
I found something called Sparse Fieldsets in JSON API, and I'm wondering if something like this exists for .NET under another name.
Update:
Talking to another coder, I realize it probably makes more sense to implement something like this between the backend and the database and make a specific call for this table. I still need to work out if I need to create a new object to support this. I think it'd still be faster if I just kept the same object but nulled out all of the connecting objects that I don't need for the table. But maybe that's considered bad practice? Also we're using Entity Framework for what it's worth.
Update 2:
I just created a new query without all of the .Include() and works well enough for what I need:
_dataContext.ApplePie
.Include(f => f.Apples).ThenInclude(f => f.Apple)
.Include(f => f.Sugars).ThenInclude(f => f.MolecularStructure)
.Include(f => f.Recipe)
Maybe you are looking for Anonymous Types?
For example, if you had a typed object with three properties, but you only wanted to operate on two:
var threePropThing = new ThreePropertyThing { Id = 1, Message = "test", ExtraProperty = "ex" };
var myAnonThing = new { Id = threePropThing.Id, Message = threePropThing.Message };
Best practice would be to not pass this anonymous object around. But, if you really needed to, you could return it as type object.
Typically, when passing data around in c#, you want to have it typed.
C# is a strongly-typed language and I would say that it is unusual for C# to support scenarios, when object definition (properties) are not known in advance, like in JSON API "fields" parameter case. Implementing this would imply using reflection to filter the properties, which is usually slow and error-prone.
When implementing C# web-services, people usually create one DTO response model per each request.
If your table has fixed set of fields, I would personally recommend to create a DTO class containing only the fields which are required for your table, and then create a method which returns this response for your specific request. While it doesn't align with "without having to define a new object" in the question, it makes the intention clear and makes it really easier to maintain the API in future.
You might want to use libraries like AutoMapper to save time and avoid duplicated code of copying the values from data model to DTO, if you have many such methods.

Fetch a component by its tcm id using the core services

I need to fetch a component based on its tcm id using the core services. Please help me which function of core service I can use along with some sample code if possible as well.
Thanks in advance!!
Check the section in the documentation, which you can find here
A basic sample (out of my head, untested ;) ):
ComponentData component = (ComponentData)client.Read(yourComponentId, new ReadOptions());
string title = component.Title;
XElement content = XElement.Parse(component.Content);
The Read method will get you an IdentifiableObjectData object, which you can cast to the needed type if you're sure about what you're supposed to be getting back.
The ReadOptions object will instruct the CoreService how to load the item, for instance, with all Keyword URI's loaded as well using LoadFlags.KeywordXlinks

List of Publication Targets using Tridion Core Service?

How would I get a list of Publication Targets with the Tridion Core Service? I see this code sample to get the Target Info, but cannot find a way to get the list from the Core Service. Maybe it is part of the Publication object?
var pubtarget = (PublicationTargetData)client.Read("tcm:0-21-65537", readoption);
Also, if there is a way to get this via the Anguilla JavaScript client it would also be cool.
var filter = new PublicationTargetsFilterData();
var pubTargets = ClientAdmin.GetSystemWideList(filter);
var pubTargetsXml = ClientAdmin.GetSystemWideListXml(filter);
You can set additional filter properties on filter object
user978511 already answered how to do it using the Core Service, so let me just answer how you can do it using Anguilla:
var system = $models.getItem($const.TCMROOT);
var list = system.getListPublicationTargets();
From then on, it's a normal list -- so you'll want to check isLoaded() and call load() if it returns false (hooking into the "load"/"loadfailed" events for the callback).
The Publication Targets are available either as XML through the getXml() method or as an array through the getItems() method (which returns an array of model items -- so again, you can check isLoaded() on those, etc.)

Mocking DbEntityEntry.CurrentValues.SetValues() in EF4 CTP5 Code First

I am trying to use the DbEntityEntry.CurrentValues.SetValues() method to facilitate updating an existing entity with values from a non-entity DTO (see: http://blogs.msdn.com/b/adonet/archive/2011/01/30/using-dbcontext-in-ef-feature-ctp5-part-5-working-with-property-values.aspx)
I'm having trouble removing the dependency on DbEntityEntry though (for mocking, testing). Here is an example of what I would like to do:
var entity = dbSet.Find(dto.Id);
var entry = context.Entry(entity);
entry.CurrentValues.SetValues(dto);
context.SaveChanges();
I've also considered:
EntityType entity = new EntityType() { Id = dto.Id };
context.Attach(entity);
var entry = context.Entry(entity);
entry.CurrentValues.SetValues(entity);
context.SaveChanges();
From what I've been able to find both seem reasonable when working with an actual DbContext, but when I abstract the context to an IMyContext I lose the capability to get a DbEntityEntry for an entity, thus losing the SetValues option.
Is there any way to work around this issue, or do I need to bite the bullet and manually set modified properties on the entity from the DTO (potentially a lot of boilerplate for entities with many properties)?
(I'm fairly new to EF and this is my first StackOverflow question, so please be gentle)
If you have never used it before, this would be a great use for AutoMapper (also available via NuGet). I am unaware of how to solve your IMyContext issue and would also resort to mapping the properties. But instead of doing so manually, I would allow AutoMapper to do the heavy lifting.

Resources