Render Blocks in json

Hi, I have built some code to render blocks as json, it works fine. but I am curious if there is a better way?.

The current way of doing it requires a hard connection between the API and the block builders. I have added code to do this dynamically, but my dynamically created types dose not show its properties when reflecting, but thy do show up in the debugger.

.GetProperties() revails no properties, dose someone know why .GetProperties() is empty or have an alternetive solution?

		[HttpGet]
	[Route("block")]
	public IHttpActionResult Get(Guid pageId, string types, Guid? channelId = null)
	{
                   ............

		List<JsonBlock> returnList = new List<JsonBlock>();
		var page = _pageService.Get(pageId);

		foreach (var blockContainer in page.Blocks)
		{
			foreach (var blockItem in blockContainer.Items.OfType<BlockItemLink>())
			{

				var blockModel = blockItem.BlockSystemId.MapTo<BlockModel>();

				if(blockModel != null)
				{
					var blockTemplate = _fieldTemplateService.Get<FieldTemplateBase>(blockModel.FieldTemplateSystemId);


					switch (blockTemplate.Id)
					{
						case "Takeover":
							TakeoverBlockViewModel takeover = blockModel.MapTo<TakeoverBlockViewModel>();
							returnList.Add(new JsonBlock { Type = blockTemplate.Id, Data = toDynamic(takeover) });
							break;

						default:
								//Try to do this dynamicly without a switch
								string typeName = "Litium.Accelerator.ViewModels.Block." + blockTemplate.Id + "BlockViewModel, Litium.Accelerator";
								string qTypeName = Type.GetType(typeName).AssemblyQualifiedName.ToString();
								Type viewModelType = Type.GetType(qTypeName);

								var viewModel = Activator.CreateInstance(viewModelType);

								Mapper.Map(blockModel, viewModel, blockModel.GetType(), viewModelType);

								returnList.Add(new JsonBlock { Type = blockTemplate.Id, Data = toDynamic(viewModel) });
							}


							break;
					}
				}



			}

		}
		return Json(returnList);
	}


	private dynamic toDynamic<t>(t obj)
	{
		IDictionary<string, object> expando = new ExpandoObject();
		var porioerties = typeof(t).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);

		foreach (var propertyinfo in porioerties)
		{
			var currentvalue = propertyinfo.GetValue(obj);

			switch (currentvalue)
			{
				case ImageModel t1:
					var imageModel = (currentvalue as ImageModel);
						expando.Add(propertyinfo.Name, new JsonMediaOptions { Thumbnail = imageModel.GetUrlToImage(Size.Empty, new Size(400, 400)).Url, Medium = imageModel.GetUrlToImage(Size.Empty, new Size(1000, 1000)).Url, Full = imageModel.GetUrlToImage(Size.Empty, Size.Empty).Url });
					break;
				default:
						expando.Add(propertyinfo.Name, currentvalue);
					break;
			}
			
		}
		return expando as ExpandoObject;
	}

Litium version: 7.3

I don’t get the idea, why don’t you just return the block model as Ok(blockModel)?

Guid’s and image filenames is not super useful in javascript, the ViewModel is what you typically want

I fixed the code:

private dynamic toDynamic(t obj)
{

	var props = typeof(t).GetProperties() //only worked for "real" objects
        var props = obj.GetType() // Workes for both

So I now have the possibility to get the ViewModels without a switch and only using naming convention, but is there a better way to solve this?

So you want to get the Url to Image value instead of Image file name or File’s system Id? I think you can do that by configure the mapping to BlockModel, to map file’s systemId to ImageUrl directly instead of to ImageModel.

I might be missing something here, dose BlockModel include the fieldTypes Type? I dont find a good way of knowing what datatype, video, image, category, product or cutsom field type the Guid fields represent without calling a BlockViewModelBuilder? Or do the mapping manually?

Yes, you can configure the mapping. In BannerBlockItemViewModel.cs you can define the mapping logic in Configure method.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.