Не удается сериализовать ISession при использовании библиотеки Newtonsoft. Json - PullRequest
0 голосов
/ 17 января 2020

Моя программа отображает следующую ошибку при попытке сохранить некоторые данные без сохранения их в базе данных и отображения в json.

Newtonsoft. Json .JsonSerializationException: 'Не удалось создать экземпляр типа Microsoft.AspNetCore.Http.ISession. Тип является интерфейсом или абстрактным классом и не может быть создан. Путь 'Session.IsAvailable', строка 1, позиция 26. '

Моя ошибка Pi c

Этот код написан с использованием шаблона дизайна репозитория , Код написанный в комментарии работает. Стоит ли менять код GetJson<T> в новой версии? после изменения с помощью Newtonsoft.Json TO с использованием System.Text.Json.Serialization?

public class CartController : Controller
{
    private  IProductRepository repository;
    private Cart _cart;
    public CartController(IProductRepository repo, Cart cart)
    {
        repository = repo;
        _cart = cart;
    }

    public ViewResult Index(string returnurl)
    {
        ViewBag.ReturnUrl = returnurl;
        //return View(GetCart());
        return View(_cart);

    }
    public IActionResult AddToCart(int ProductID,string returnUrl)
    {
        Product product = repository.GetById(ProductID);
        if (product != null)
        {
            //Cart cart = GetCart();
            //cart.AddItem(product, 1);
            //SaveCart(cart);
            _cart.AddItem(product, 1);
        }
        return RedirectToAction("Index", new { returnUrl });
    }
    public IActionResult RemoveFromCart(int ProductID, string returnUrl)
    {
        Product product = repository.GetById(ProductID);
        if (product != null)
        {
            //Cart cart = GetCart(); //-----> Worked
            //cart.RemoveLine(product); //-----> Worked
            //SaveCart(cart); //-----> Worked
            _cart.RemoveLine(product); //Not Working
        }
        return RedirectToAction("Index", new { returnUrl });
    }
    //private Cart GetCart() //-->Worked
    //{
    //    Cart cart = HttpContext.Session.GetJson<Cart>("Cart") ?? new Cart();
    //    return cart;
    //}
    //private void SaveCart(Cart cart) //-->Worked
    //{
    //    HttpContext.Session.SetJson("Cart", cart);
    //}
}



 public static class SessionExtensions
{

    public static void SetJson(this ISession session, string key, object value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }
    public static T GetJson<T>(this ISession session, string key)
    {

        var value = session.GetString(key);

        return value == null ? default(T) :
            JsonConvert.DeserializeObject<T>(value); //error exception throw here
    }

}

и:

     public  class SessionCart : Cart
      {
       public static Cart GetCart(IServiceProvider services)
       {

        ISession session = services.GetRequiredService<IHttpContextAccessor>()?.HttpContext.Session;
        SessionCart cart = session?.GetJson<SessionCart>("Cart") ?? new SessionCart();
        cart.Session = session;
        return cart;
    }
    [JsonIgnore]
    public ISession Session { get; set; }
    public override void AddItem(Product product, int quantity)
    {
        base.AddItem(product, quantity);
        Session.SetJson("Cart", this);
    }
    public override void RemoveLine(Product product)
    {
        base.RemoveLine(product);
        Session.SetJson("Cart", this);
    }
    public override void Clear()
    {
        base.Clear();
        Session.Remove("Cart");
    }
}

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Я вижу, что вы читаете книгу Адама Фримена Pro ASP. NET Core 2 MVC.

Чтобы исправить эту проблему, измените модификатор доступа в переменной ISession с * От 1004 * до private. Это предотвратит сериализацию ISession и затем будет десериализована так, как вы ожидаете.

До:

 [JsonIgnore]
 public ISession Session { get; set; }

После:

 private ISession session { get; set; }

Затем убедитесь, что все ваши методы можно использовать строчную букву session (чтобы следовать рекомендациям по именованию).

0 голосов
/ 17 января 2020

Просто добавьте следующее пространство имен в класс SessionCart.

using Newtonsoft.Json;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...