Mediapicker field pb : ProductImage: ((MediaPickerField)productQuantity.Product.Fields.FirstOrDefault(f => f.Name == "ProductImage")), not works

Topics: Customizing Orchard, Troubleshooting
Feb 28, 2013 at 6:22 AM
Edited Feb 28, 2013 at 8:19 AM
I am very puzzled by mediapicker field and its rendering.
Using Nwazet commerce I discovered that the following line in ShoppingCartController does not work
 ProductImage: ((MediaPickerField)productQuantity.Product.Fields.FirstOrDefault(f => f.Name == "ProductImage")),
The final game is to extract the url from code, any idea ?
Mar 2, 2013 at 11:41 PM
How does it not work?
Mar 3, 2013 at 8:14 AM
Edited Mar 3, 2013 at 8:15 AM
I get null, it is in the shoppingcart driver widget or full, there is null in the fields collection when the same product display correctly its image in AdminSummary and normal displaytypes.
MediaPickerField is so strange, for example when you display the part (product here) where it has been added, it is not displayed in this part but get displayed after it using the mediapicker models...where is its/my mind...
PS: I am using the last clayless, source, but I had the same problem before switching.
Mar 4, 2013 at 12:27 AM
Is the field named ProductImage, and is it on ProductPart?
Mar 4, 2013 at 5:38 AM
Yes the model is Summary or Detail, nothing for a special placement in info file.
Mar 4, 2013 at 5:47 AM
I don't understand. That code is working just fine for me. What's different in your case?
Mar 4, 2013 at 7:43 AM
I will eventually do a clean install of Nwazet.commerce to check the differences, but a little busy actually as I need to start a web site, after I will publish my code on bitbucket.
What is strange is that in debugger for this shopping cart display I get nothing in the fields for this product ?
Mar 4, 2013 at 8:40 AM
My ProductPart is obtained with : contentManager.Get<ProductPart>(ProductId)
Should the fields not being loaded ?
Mar 4, 2013 at 5:16 PM
They should. Did you try to attach a debugger and verify the contents of the parts?
Mar 4, 2013 at 8:02 PM
Edited Mar 4, 2013 at 8:09 PM
Spent many hours on this, everything is here but the fields....
As I already had a problem with the interaction I reported between nwazet.commerce and any other contentype using a mediapicker field (the special alternate injected in code was taking precedence on any normal AdminSummary display),
I abandoned sometimes, going on other priorities and hopping that someone on forum could help me.
Mar 4, 2013 at 8:53 PM
You mean you saved data for those fields but there is nothing in the field storage? What about in the database?
Mar 4, 2013 at 9:54 PM
Edited Mar 14, 2013 at 10:38 AM
When I edit the product everything is here.
And in 'detail' display I get the images ???
I agree that if it works on your side I have to find the difference, the onlyI see is a custom type using a mediapickerfield but there could be many others.
Mar 14, 2013 at 11:24 AM
Edited Mar 14, 2013 at 11:27 AM
the puzzling picture

what is this ContentPart that contains the ProductPart field when there is already a productPart without its field ??
Seems a bug
Mar 14, 2013 at 1:27 PM
Could you annotate that picture pointing to the bug that you think you see? I see none, but then again there are a lot of rows in that picture :)
Could it be that you're confused and that there is actually no ContentPart that contains no ProductPart, but that it's actually the ContentItem that has the ProductPart?
Mar 14, 2013 at 1:37 PM
Edited Mar 14, 2013 at 1:40 PM
My mind is that this supplemntary contentPart has no reason to be here, if you follow the migration files, the Product content Type has only be extended from the original version with 2 parts we find here: RoleAssignment and ProductRecommendation, the others are traditional system related, but where come from the content part I developped in the debugger ?
And why is it containing the Field which belongs from the origin to the ProductPart as defined in the original and unchanged migration ???
I deleted and rereated the mappings.bin file to be sure everything was uptodate (because this file not always update after running a migration ??? but I could work with this)
Mar 14, 2013 at 4:29 PM
Mappings.bin file has nothing to do with the content definitions.
When you login to the dashboard, do you see all the parts attached to Product? If not, then there are probably ActivatingFilters doing the work. If there are, simply delete them and update your migration files to not add them.
Mar 14, 2013 at 4:32 PM
Edited Mar 14, 2013 at 4:33 PM
Just to give some context to what Christian is saying, here is the relevant part of the migration:
              builder => builder.Attachable());

            ContentDefinitionManager.AlterTypeDefinition("Product", cfg => cfg
              .WithPart("AutoroutePart", builder => builder
                  .WithSetting("AutorouteSettings.AllowCustomPattern", "true")
                  .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false")
                  .WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Title', Pattern: '{Content.Slug}', Description: 'my-product'}]")
                  .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))

              builder => builder.WithField("ProductImage", fieldBuilder => fieldBuilder.OfType("MediaPickerField").WithDisplayName("Product Image")));
            return 1;
What you should notice here is that there are two parts involved: ProductPart part, which is defined in code and has the Sku, Price, etc., and the Product code, which is dynamic, has no code counterpoint, and is just the convention for the default part where Orchard manages the fields from the UI (it has the same name as the content type is the convention). Note that the field is attached to the latter, not the former. This is so that the filed can easily be managed (and deleted if necessary) from the admin.
Mar 14, 2013 at 6:02 PM
Makes perfect sense.
Mar 14, 2013 at 6:20 PM
Ok, perfect trick.

If it explains this supplementary content part, then how could I access my mediapicker field named ProductImage ?

Why is it working in one case and not in the other (unfortunately mine )

I will try something as this, considering I know a ProductPartRecord object:
            dynamic p = contentManager.Get<ProductPart>(Product.Id);
            ContentField f = ((IEnumerable<ContentField>)p.Fields).FirstOrDefault(f => f.Name == "ProductImage");
Mar 14, 2013 at 6:40 PM
I'd do p.Product.ProductImage
Mar 14, 2013 at 10:48 PM
Edited Mar 14, 2013 at 10:48 PM
Terrific my shoppingcart is exploding with images.
Could you give some more detail on this dynamic programming magic ?
What is exactly the result of Get<ProductPart> and how does this manages to find this field not in the part of class productpart ?

Is the VS2012 debugger inspector always showing the real thing when dealing with dynamic objects ?
Mar 14, 2013 at 11:22 PM
ContentItem implements the interfaces for dynamic. It enables you to get all parts directly, as dynamic objects themselves, which enables you to get at the fields. What's really neat about this is that it works the same for parts defined in code, and parts defined by metadata in the admin.

In this specific case, I would not use Get<T> (which returns the part of type T, that you;re not using here. Instead, use the regular Get, that gets you a ContentItem.

What do you mean "the real thing"?
Mar 14, 2013 at 11:38 PM
Edited Mar 15, 2013 at 7:53 AM
When debuging I noticed that I can't trace through some details of dynamic calls, may be another hidden option to set, but I think I have set everything ok.
From this constat, I was questionning myself on the data view presented in the various watch or quickwatch windows: if some dynamics calls are not follows is the structure displayed the correct one ?
Mar 15, 2013 at 12:49 AM
No, dynamic is definitely trickier to debug. There is no "correct one" per se. This works like Ruby's method_missing: there is no list of everything available: the runtime just passes the name of a member, and the object decides dynamically if there is something behind. It could choose to return something for absolutely every possible name for all you know. We can give the debugger hints (and we do), but that is a clear limitation of dynamic (and a price for its amazing flexibility).