C# 为什么HttpContext.Session.Get上的相关表值为空使用列表<>;?

C# 为什么HttpContext.Session.Get上的相关表值为空使用列表<>;?,c#,asp.net,model-view-controller,core,C#,Asp.net,Model View Controller,Core,我正在开发一个购物车(使用MVC Asp.NETCore2.2和EF) 有3个表(模型类): 普罗杜托 Tamanho(与Produto表相关) TipoMassa(与Produto表相关) 在ProductController类中,我创建了一个存储在会话中的列表,用于在CartController类中获取该列表 但是,当我试图在CartController类中获取该列表时,来自相关表(Tamanho和TipoMassa)的值为空。该列表仅包含Produto表的值 我怎样才能修好它 Prod

我正在开发一个购物车(使用MVC Asp.NETCore2.2和EF)

有3个表(模型类):

  • 普罗杜托
  • Tamanho(与Produto表相关)
  • TipoMassa(与Produto表相关)
在ProductController类中,我创建了一个存储在会话中的列表,用于在CartController类中获取该列表

但是,当我试图在CartController类中获取该列表时,来自相关表(Tamanho和TipoMassa)的值为空。该列表仅包含Produto表的值

我怎样才能修好它

Produto控制器类
public ActionResult AddToCart(IFormCollection)
{
字符串Nome=集合[“Nome”];
字节IdTamanho=Convert.ToByte(集合[“IdTamanho”]);
字节IdTipoMassa=Convert.ToByte(集合[“IdTipoMassa]”);
var produtoContext=\u context.Produto
.包括(c=>c.IdCategoriaNavigation)
.包括(c=>c.idtamanhanvigation)
.Include(c=>c.IdTipoMassaNavigation)
.FirstOrDefault(p=>p.Nome==Nome&&p.IdTamanho==IdTamanho
&&p.IdTipoMassa==IdTipoMassa);
if(produtoContext==null)
{
返回NotFound();
}
//添加一个会话
List itens=新列表();
itens=HttpContext.Session.Get(“itens”);
如果(itens==null)
{
itens=新列表();
}
itens.Add(produtoContext);
HttpContext.Session.Set(“itens”,itens);
TempData[“save”]=“Adicionado com successo”;
返回重定向到操作(名称(索引),“Produto”);
}
  • 很好! 但是在[CartController]的IDCategorizanavigation中,IdTamanhoNavigation和IdTipoMassaNavigation为空。代码如下
购物车控制器类
public IActionResult Index()
{
列出itens=HttpContext.Session.Get
(“itens”);
如果(itens==null)
{
itens=新列表();
}
返回视图(itens.ToList());
}
  • 当我试图在视图中显示这些值时,相关的表值(IdCategoriaNavigation、IdTamanhoNavigation和IdTipoMassaNavigation)为空。代码如下
购物车视图
@foreach(模型中的变量项)
{
2x
@DisplayFor(modeleItem=>item.Nome)

@DisplayFor(modeleItem=>item.descripcao) @如果(item.IdCategoria==1) { @DisplayFor(modeleItem=>item.IdTamanhoNavigation) @DisplayFor(modeleItem=>item.IdTamanhoNavigation.Valor) @DisplayFor(model=>item.IdTipoMassaNavigation) @DisplayFor(modeleItem=>item.IdTipoMassaNavigation.Valor) } 2x R$@Html.DisplayFor(modelItem=>item.Preco) }
Produto模型类
公共部分类Produto
{
公共产品()
{
Cardapio=newhashset();
ItensPedido=newhashset();
Promocao=新的HashSet();
}
public int IdProduto{get;set;}
public int IdCategoria{get;set;}
公共字节IdTamanho{get;set;}
公共字节IdTipoMassa{get;set;}
公共字符串Nome{get;set;}
公共字符串描述符{get;set;}
公共字符串Imagem{get;set;}
[列(TypeName=“十进制(18,2)”)]
公共十进制预编译{get;set;}
公共bool IsAtivo{get;set;}
[JsonIgnore]
公共虚拟Categoria IdCategoriaNavigation{get;set;}
[JsonIgnore]
公共虚拟Tamanho IdTamanhoNavigation{get;set;}
[JsonIgnore]
公共虚拟TipoMassa IDTipomassa导航{get;set;}
公共虚拟ICollection Cardapio{get;set;}
公共虚拟ICollection ItensPedido{get;set;}
公共虚拟ICollection{get;set;}
}
塔曼霍模型班
公共部分类Tamanho
{
公共塔曼霍()
{
Produto=新的HashSet();
}
公共字节IdTamanho{get;set;}
公共字符串值{get;set;}
公共虚拟ICollection Produto{get;set;}
}
蒂波马萨模型班
公共部分类TipoMassa
{
公共提波马萨()
{
Produto=新的HashSet();
}
公共字节IdTipoMassa{get;set;}
公共字符串值{get;set;}
公共虚拟ICollection Produto{get;set;}
}

我想在ShoppingCart视图中显示所有值。

除非我弄错了,否则我认为lambda函数存在问题:

而不是

@Html.DisplayFor(modelItem => item.IdTamanhoNavigation)
                              ^^^
您需要引用正确的输入参数(modelItem):


我忘了说我一直在使用JSon将该列表序列化到会话中。 但我必须在Produto模型类的相关方法上使用[JsonIgnore], 如果没有,当包含那些相关的表值时,我从Newtonsoft.Jason那里得到一个错误

如你所见,贝娄

关于ShoppingCart控制器类 JsonSerializationException:检测到类型为“Pianino.Models.Produto”的自引用循环。 路径“[0]。IdCategoriaNavigation.Produto”。 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference(JsonWriter编写器、对象值、JsonProperty属性、JsonContract合同、JsonContainerContract容器合同、JsonProperty容器属性)

即使是对第一篇文章的评论,我对Idtamannonavigation和IdTipoMassaNavigation也有同样的评论

因此,使用下面的[JsonIgnore],我修复了这个错误。另一方面,当我从ShoppingCart控制器类上的会话中获取列表时,这些值变为null

关于Produto模型类 论效用类
公共静态类SessionExtensions
{
公共静态无效集(此ISession会话,
public IActionResult Index()
{
    List<Produto> itens = HttpContext.Session.Get<List<Produto>>
            ("itens");
    if (itens == null)
    {
        itens  = new List<Produto>();
    }
    return View(itens.ToList());
}
 @foreach (var item in Model)
 {
  <tr>
      <td>
          <small class="text-muted"> 2x </small>
      </td>
      <td>
           @Html.DisplayFor(modelItem => item.Nome)
           <br />
           <small class="text-muted">@Html.DisplayFor(modelItem => item.Descricao)</small>

            @if (item.IdCategoria == 1)
            {
              <small class="text-dark font-italic">
                  <label for="idTamanho"> 
                     @Html.DisplayFor(modelItem => item.IdTamanhoNavigation)
                  </label>
                    @Html.DisplayFor(modelItem => item.IdTamanhoNavigation.Valor)
              </small>

              <small class="text-dark font-italic">
                    <label for="idTamanho"> @Html.DisplayFor(model => item.IdTipoMassaNavigation)</label>
                      @Html.DisplayFor(modelItem => item.IdTipoMassaNavigation.Valor)
              </small>
             }
        </td>
        <td class="text-right">
             2x R$ @Html.DisplayFor(modelItem => item.Preco)
        </td>
        <td class="align-content-end">
             <a asp-controller="Produto" asp-action="RemoveFromCart" asp-route-id="@item.IdProduto" class="text-white">
                 <i class="fa fa-times text-info"></i>
             </a>
        </td>
 </tr>
 }
public partial class Produto
{
    public Produto()
    {
        Cardapio = new HashSet<Cardapio>();
        ItensPedido = new HashSet<ItensPedido>();
        Promocao = new HashSet<Promocao>();
    }

    public int IdProduto { get; set; }
    public int IdCategoria { get; set; }
    public byte IdTamanho { get; set; }
    public byte IdTipoMassa { get; set; }
    public string Nome { get; set; }
    public string Descricao { get; set; }
    public string Imagem { get; set; }

    [Column(TypeName = "decimal(18, 2)")]
    public decimal Preco { get; set; }
    public bool IsAtivo { get; set; }

    [JsonIgnore]
    public virtual Categoria IdCategoriaNavigation { get; set; }
    [JsonIgnore]
    public virtual Tamanho IdTamanhoNavigation { get; set; }
    [JsonIgnore]
    public virtual TipoMassa IdTipoMassaNavigation { get; set; }
    public virtual ICollection<Cardapio> Cardapio { get; set; }
    public virtual ICollection<ItensPedido> ItensPedido { get; set; }
    public virtual ICollection<Promocao> Promocao { get; set; }
}
public partial class Tamanho
{
    public Tamanho()
    {
        Produto = new HashSet<Produto>();
    }

    public byte IdTamanho { get; set; }
    public string Valor { get; set; }

    public virtual ICollection<Produto> Produto { get; set; }
}
public partial class TipoMassa
{
    public TipoMassa()
    {
        Produto = new HashSet<Produto>();
    }

    public byte IdTipoMassa { get; set; }
    public string Valor { get; set; }

    public virtual ICollection<Produto> Produto { get; set; }
}
@Html.DisplayFor(modelItem => item.IdTamanhoNavigation)
                              ^^^
@Html.DisplayFor(modelItem => modelItem.IdTamanhoNavigation)
                                 ^^^
public ActionResult AddToCart(IFormCollection collection)
{
    ...

    var produtoContext = _context.Produto
        .Include(c => c.IdCategoriaNavigation)
         ^^^^
        .Include(c => c.IdTamanhoNavigation)
         ^^^^
        .Include(c => c.IdTipoMassaNavigation)
         ^^^^
       .FirstOrDefault(p => p.Nome == Nome && p.IdTamanho == IdTamanho 
    && p.IdTipoMassa == IdTipoMassa);

    ... 

    The produtoContex here, normally has all the values from the related tables.
        {PianoPizza.Models.Categoria} 
        {PianoPizza.Models.Tamanho}
        {PianoPizza.Models.TipoMassa}

        But when I set the List on Session I got the Json error.     

    HttpContext.Session.Set("itens", itens);
                        ^^^^
    ...
 }
 [JsonIgnore]
 public virtual Categoria IdCategoriaNavigation { get; set; }
 [JsonIgnore]
 public virtual Tamanho IdTamanhoNavigation { get; set; }
 [JsonIgnore]
 public virtual TipoMassa IdTipoMassaNavigation { get; set; }
public static class SessionExtensions
{

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

    public static T Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);

        return value == null ? default(T) :
            JsonConvert.DeserializeObject<T>(value);
    }
}