Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • crisweb 18 posts 88 karma points
    Nov 16, 2024 @ 23:51
    crisweb
    0

    ModelBindingException

    Good evening, I created a compenent called cart, it contain's a file cart.component.cs: using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Web; using Paris.Site.Controllers; using System.Collections.Generic; using Umbraco.Cms.Web.Common.PublishedModels; using Paris.Site.Views.Components.Cart; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging;

    namespace Paris.Site.Views.Components { [ViewComponent(Name = "Cart")] public class CartComponent : ViewComponent { private readonly IUmbracoContextAccessor _contextAccessor;

        public CartComponent(IUmbracoContextAccessor contextAccessor)
        {
            _contextAccessor = contextAccessor;
        }
    
        public IViewComponentResult Invoke()
        {
            var cartItem = new CartItem();
            var umbracoContext = _contextAccessor.GetRequiredUmbracoContext();
    
            var contenuti = umbracoContext?.PublishedRequest?.PublishedContent;
    
            //  var content = contenuti?.ContentType;
            // var contento = content.PropertyTypes.ToList();
    
            if (contenuti == null) return View(cartItem);
    
    
            cartItem.Id = contenuti.Id;
    
            cartItem.CatModello = contenuti.Value<string>("catModello");
            cartItem.CatCodice = contenuti.Value<string>("catCodice");
            cartItem.CatDettImmagine = contenuti.Value<IPublishedContent>("CatDettImmagine");
    
            return View(cartItem);
        }
    
    
    
    
    
    }
    

    } A file cartitems.cs: using Umbraco.Cms.Core.Models.PublishedContent;

    namespace Paris.Site.Views.Components.Cart { public class CartItem { public int? Id { get; set; } public string? CatModello { get; set; } public int? Quantity { get; set; } public IPublishedContent? CatDettImmagine { get; set; } public string? ImageUrl { get; set;} public string? CatCodice { get; set; }

    }
    

    } A file default.cshtml: @model Paris.Site.Views.Components.Cart.CartItem

    @if (Model != null) { @using (Html.BeginUmbracoForm("AddToCart", "Cart", FormMethod.Post)) { var imageUrl = Model.CatDettImmagine.Url();

                <input type="hidden" name="id" value="@Model.Id" />
                <input type="hidden" name="catModello" value="@Model.CatModello" />
                <input type="hidden" name="CatCodice" value="@Model.CatCodice" />      
                <input type="number" name="quantity" id="quantity-input" value="1" min="1" />
                <input type="hidden" name="imageUrl" value="@imageUrl" />
                <div class="tp-product-details-add-to-cart">
                    <button type="submit" class="tp-product-details-add-to-cart-btn w-100">ADD TO CART</button>
                </div>
                <div class="tp-product-info">
                    <div class="tp-product-details-quantity">
                        <div class="tp-product-quantity">
                            <input class="tp-cart-input" type="number" value="1" id="quantity-input" min="1">
                            <span class="tp-cart-plus" id="increment-btn">
                                <i class="fa-regular fa-angle-up"></i>
                            </span>
                            <span class="tp-cart-minus" id="decrement-btn">
                                <i class="fa-regular fa-angle-down"></i>
                            </span>
                        </div>
                    </div>
                </div>
        }
        <script>
            document.addEventListener("DOMContentLoaded", function () {
                const incrementBtn = document.getElementById('increment-btn');
                const decrementBtn = document.getElementById('decrement-btn');
                const quantityInput = document.getElementById('quantity-input');
    
                incrementBtn.addEventListener('click', function () {
                    let currentValue = parseInt(quantityInput.value);
                    quantityInput.value = currentValue + 1;
                });
    
                decrementBtn.addEventListener('click', function () {
                    let currentValue = parseInt(quantityInput.value);
                    if (currentValue > 1) {
                        quantityInput.value = currentValue - 1;
                    }
                });
            });
        </script>
    

    } else {

    Nessun prodotto disponibile.

    } It works out perfectly, then I created a surface controller called cartcontroller: using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using Newtonsoft.Json; using Paris.Site.Views.Components.Cart; using Umbraco.Cms.Web.Website.Controllers; using Umbraco.Cms.Core.Web; using Umbraco.Cms.Infrastructure.Persistence; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Logging; using Umbraco.Cms.Core.Routing; using Microsoft.AspNetCore.Http; using Umbraco.Cms.Web.Common.UmbracoContext; using Umbraco.Cms.Core.Models.PublishedContent;

    namespace Paris.Site.Controllers { public class CartController : SurfaceController { private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger

        [HttpPost]
        public IActionResult AddToCart(int id, string catModello, int quantity, string imageUrl, string catCodice)
        {
            var cart = Session.GetObjectFromJson<List<CartItem>>("Cart") ?? new List<CartItem>();
            var item = cart.Find(i => i.Id == id);
            if (item == null)
            {
                cart.Add(new CartItem { Id = id, CatModello = catModello, Quantity = quantity, ImageUrl = imageUrl, CatCodice = catCodice });
            }
            else
            {
                item.Quantity += quantity;
            }
            Session.SetObjectAsJson("Cart", cart);
    
            var referer = Request.Headers["Referer"].ToString();
            _logger.LogInformation("Redirecting to: {referer}", referer);
    
            return Redirect(referer);
        }
    
        [HttpPost]
        public IActionResult RemoveFromCart(int id)
        {
            var cart = Session.GetObjectFromJson<List<CartItem>>("Cart") ?? new List<CartItem>();
            var item = cart.Find(i => i.Id == id);
            if (item != null)
            {
                cart.Remove(item);
            }
            Session.SetObjectAsJson("Cart", cart);
            var referer = Request.Headers["Referer"].ToString();
            _logger.LogInformation("Redirecting to: {referer}", referer);
    
            return Redirect(referer);
        }
    
        [HttpGet]
        private IPublishedContent GetUmbracoProduct(int productId)
        {
            using (var umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext())
            {
                var content = umbracoContextReference.UmbracoContext.Content.GetById(productId);
                if (content == null)
                { _logger.LogWarning($"Prodotto con ID {productId} non trovato."); }
                return content;
            }
        }
        [HttpGet]
        public IActionResult Index()
            {
                var cart = Session.GetObjectFromJson<List<CartItem>>("Cart") ?? new List<CartItem>();
                return View(cart);
            }
    
        [HttpGet]
        public IActionResult GetCartItemCount()
        {
            var cart = Session.GetObjectFromJson<List<CartItem>>("Cart") ?? new List<CartItem>();
            _logger.LogInformation("Cart item count: {count}", cart.Count);
            return Json(cart.Count);
        }
    
    
    
    
    
    }
    

    } Then I created in the root view/cart/index.cshtml:

    @model List

    Carrello Vista

    @foreach (var item in Model) { }
    Id Immagine CatModello Quantità Codice
    @item.Id @item.CatModello @item.Quantity @item.CatCodice

    @*

    // Pulsante rimuovi
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            fetch('/CartSurface/GetCartItemCount')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('cart-item-count').innerText = data;
                })
                .catch(error => console.error('Error fetching cart item count:', error));
        });
    </script>
    *@

    It works out perfectly. I created in the Umbraco's backoffice a document type with alias Cart with a template clled cart with layout MasterInterna.cshtml, the content model components are shown as expected, I created a cartViewModel: using System.Collections.Generic; using Umbraco.Cms.Core.Models.PublishedContent;

    namespace Paris.Site.Views.Components.Cart { public class CartViewModel { public IPublishedContent Content { get; set; } // Nodo Umbraco corrente public List

    I can't render in the partial view (cart.cshtml) coming from the controller, it always gives me the same error: An unhandled exception occurred while processing the request. ModelBindingException: Cannot bind source type Umbraco.Cms.Core.Models.ContentModel to model type Paris.Site.Views.Components.Cart.CartViewModel. Umbraco.Cms.Web.Common.ModelBinders.ContentModelBinder.ThrowModelBindingException(bool sourceContent, bool modelContent, Type sourceType, Type modelType) Any suggestion on how to solve it? Please help me, thank you.

Please Sign in or register to post replies

Write your reply to:

Draft