首页 > 解决方案 > 将视图模型发送到局部视图时,为什么会出现类型错误 (InvalidOperationException)?

问题描述

当我尝试将模型视图发送到我自己的局部视图时,它会给出一个错误,即它们的类型不同。

看到这是我的服务:

  public Category GetCategoryByCategoryURL(string url)
        {
            return _context.
                Categories.
                Where(c=>c.CategoryURL== "https://localhost:44374/"+url)
                .Single();
        }

哪个工作没有任何问题。我的控制器的底部是:

 [Route("/{url}")]
        public IActionResult CategoryChooser(string url)
        {
            Category cat = _categoryService.GetCategoryByCategoryURL(url);
            return View(cat);
        }

选择类别并将其发送到主视图。这是主要观点:

@using PipeLandProject.Core.DTOs.Category
@model PipeLandProject.DataLayer.Entities.Category.Category
@{
    ViewData["Title"] = Model.CategoryTitle;

}
<div class="container">
    <nav aria-label="breadcrumb">
        <ul class="breadcrumb">
            <li class="breadcrumb-item"><a href="/">صفحه اصلی</a></li>
            <li class="breadcrumb-item active" aria-current="page">@Model.CategoryTitle</li>
        </ul>
    </nav>
</div>
<main>
    <div class="container">
        <div class="row mb-2">
            <h1>@Model.CategoryTitle</h1>
            <p>@Model.CategoryContent</p>
            <h3>آیدی دسته: @Model.CategoryId</h3>
            <img src="/CategoryImage/Image/@Model.CategoryImageName" alt="@Model.CategoryTitle">
            <p>@Model.CategoryMetaDescription</p>
            <a href="@Model.CategoryURL" title="@Model.CategoryTitle">آدرس صفحه</a>
            <img src="/CategoryImage/DemoFile/@Model.DemoFileName" alt="@Model.CategoryTitle"/>
            @*<partial name="ListCategory" />
            <partial name="CategoryContent" />*@
        </div>
    </div>
</main>

当我运行它时没有任何问题,但我想使用部分。此页面有 2 个部分。一部分是网站主要类别的列表,另一部分是同一类别的内容。现在 ViewModel 如下:

 public class ShowListCategoryViewModel
    {
        public string CategoryTitle { get; set; }
    }

服务:

 public List<ShowListCategoryViewModel> ShowAllCategoryForSideBar()
        {
            return _context.Categories.Select(
                c => new ShowListCategoryViewModel()
                {
                    CategoryTitle = c.CategoryTitle
                }).ToList();
        }

并查看此部分:

@model PipeLandProject.Core.DTOs.Category.ShowListCategoryViewModel
<div class="col-lg-3 col-md-3 col-sm-12">
    <div class="position-sticky px-0 mx-0">
        <h2 class="h4 font-weight-bold">دسته بندی سایت</h2>
        <hr/>
        <ul class="list-group shadow">

            @for (int i = 0; i < Model.CategoryTitle.Length; i++)
            {
                <li class="list-group-item d-flex justify-content-between align-items-center">
                    <a href="" class="">@Model.CategoryTitle</a>
                    <span class="px-2 badge badge-primary badge-pill">12</span>
                </li>
            }
        </ul>
    </div>
</div>

页面的第二部分:

模型视图页面的内容部分:

 public class ShowCategoryContentViewModel
    {
        public string CategoryTitle { get; set; }
        public string CategoryImageName { get; set; }
        public string CategoryContent { get; set; }
        public string DemoFile { get; set; }
    }

服务:

public ShowCategoryContentViewModel ShowContentOfCategory(string url)
        {
            return _context.Categories
                .Where(c => c.CategoryURL == url)
                .Select(c=>new ShowCategoryContentViewModel()
                {
                    CategoryImageName = c.CategoryImageName,
                    CategoryContent = c.CategoryContent,
                    CategoryTitle = c.CategoryTitle,
                    DemoFile = c.DemoFileName
                })
                .Single();
        }

部分观点:

@model PipeLandProject.Core.DTOs.Category.ShowCategoryContentViewModel

<div class="col-lg-9 col-md-9 col-sm-12">
    <h1 class="font-weight-bold">@Model.CategoryTitle</h1>
    <hr />
    <p>
        @Model.CategoryContent
    </p>
    <img src="/CategoryImage/@Model.CategoryImageName" />
</div>

此错误显示以下内容。它根本不允许运行。一般来说,我想将模型视图传递给局部视图。 错误部分 1

如果我不将模型发送到部分,则会出现错误文本: 错误部分 2

我的项目由3层组成,第一层是核心,与数据库有关。在这一层中,有模型视图和其他部分,如接口和服务。第二层是数据库层,第三层是web层,与核心层相关。我在核心层使用接口,它的服务在同一层实现。以下代码是类别的完整服务部分:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Http;
using PipeLandProject.Core.Convertors;
using PipeLandProject.Core.DTOs.Category;
using PipeLandProject.Core.Generator;
using PipeLandProject.Core.Security;
using PipeLandProject.Core.Services.Interfaces;
using PipeLandProject.DataLayer.Context;
using PipeLandProject.DataLayer.Entities.Category;

namespace PipeLandProject.Core.Services
{
    public class CategoryService : ICategoryService
    {
        private PipeLandProjectContext _context;

        public CategoryService(PipeLandProjectContext context)
        {
            _context = context;
        }
        public int AddCategory(Category category)
        {
            _context.Categories.Add(category);
            _context.SaveChanges();
            return category.CategoryId;
        }

        public int AddCategory(Category category, IFormFile imgCategory, IFormFile categoryDemo)
        {
            category.CategoryImageName = "default.png";
            if (imgCategory != null && imgCategory.IsImage())
            {
                category.CategoryImageName=
                    NameGenerator.GenerateUniqCode() + Path.GetExtension(imgCategory.FileName);
                string imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage/Image/", category.CategoryImageName);

                using (var stream = new FileStream(imagePath, FileMode.Create))
                {
                    imgCategory.CopyTo(stream);
                }
                #region Image Resize

                ImageConvertor imgResizer = new ImageConvertor();
                string ThumbPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage/Thumb/", category.CategoryImageName);

                imgResizer.Image_resize(imagePath, ThumbPath, 150);

                #endregion
                #region UpLoad Demo File

                if (categoryDemo != null)
                {
                    category.DemoFileName =
                        NameGenerator.GenerateUniqCode() + Path.GetExtension(categoryDemo.FileName);
                    string demoPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage/DemoFile/", category.DemoFileName);
                    using (var stream = new FileStream(demoPath, FileMode.Create))
                    {
                        categoryDemo.CopyTo(stream);
                    }
                }

                #endregion
            }
            _context.Categories.Add(category);
            _context.SaveChanges();

            return category.CategoryId;
        }

        public int AddCategoryFromAdmin(CreateCategoryViewModel category, IFormFile imgCategory, IFormFile categoryDemo)
        {
            Category addCategory = new Category();
            addCategory.CategoryTitle = category.CategoryTitle;
            addCategory.CategoryContent = category.CategoryContent;
            addCategory.CategoryMetaDescription = category.CategoryMetaDescription;
            addCategory.CategoryURL = category.CategoryURL;
            //if (category.CategoryImage != null)
            //{
            //    string imagePath = "";
            //    addCategory.CategoryImageName = NameGenerator.GenerateUniqCode() + Path.GetExtension(category.CategoryImage.FileName);
            //    imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage", addCategory.CategoryImageName);
            //    using (var stream = new FileStream(imagePath, FileMode.Create))
            //    {
            //        category.CategoryImage.CopyTo(stream);
            //    }
            //}
            addCategory.CategoryImageName = "default.png";
            if (imgCategory != null && imgCategory.IsImage())
            {
                addCategory.CategoryImageName =
                    NameGenerator.GenerateUniqCode() + Path.GetExtension(imgCategory.FileName);
                string imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage/Image/", addCategory.CategoryImageName);

                using (var stream = new FileStream(imagePath, FileMode.Create))
                {
                    imgCategory.CopyTo(stream);
                }
                #region Image Resize

                ImageConvertor imgResizer = new ImageConvertor();
                string ThumbPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage/Thumb/", addCategory.CategoryImageName);

                imgResizer.Image_resize(imagePath, ThumbPath, 150);

            }
            #endregion
            #region UpLoad Demo File
            if (categoryDemo != null)
            {
                addCategory.DemoFileName =
                    NameGenerator.GenerateUniqCode() + Path.GetExtension(categoryDemo.FileName);
                string demoPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage/DemoFile/", addCategory.DemoFileName);
                using (var stream = new FileStream(demoPath, FileMode.Create))
                {
                    categoryDemo.CopyTo(stream);
                }
            }
            #endregion
            _context.Categories.Add(addCategory);
            _context.SaveChanges();
            return addCategory.CategoryId;
        }

        public void DeleteCategory(int categoryId)
        {
            Category category = GetCategoryByCategoryId(categoryId);
            category.IsDelete = true;
            UpdateCategory(category);
        }

        public void EditCategoryFromAdmin(EditCategoryForAdminViewModel edit)
        {
            Category category = GetCategoryByCategoryId(edit.CategoryId);
            category.CategoryTitle = edit.CategoryTitle;
            category.CategoryURL = edit.CategoryTitle;
            category.CategoryContent = edit.CategoryContent;
            category.CategoryMetaDescription = edit.CategoryMetaDescription;
          

            if (edit.CategoryImageName != null)
            {
                #region Delete Old Image Category   
                if (edit.CategoryImageName != "Default.jpg")
                {
                    string deletePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage", edit.CategoryImageName);
                    if (File.Exists(deletePath))
                    {
                        File.Delete(deletePath);
                    }
                }
                #endregion

                #region Save New Image Category
                //category.CategoryImageName = NameGenerator.GenerateUniqCode() + Path.GetExtension(edit.CategoryImage.FileName);
                //string imagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/CategoryImage", category.CategoryImageName);
                //using (var stream = new FileStream(imagePath, FileMode.Create))
                //{
                //    edit.CategoryImageName.CopyTo(stream);
                //}
                #endregion

            }
            _context.Categories.Update(category);
            _context.SaveChanges();
        }


        public List<ShowCategoryForAdminViewModel> GetCategoriesForAdmin()
        {
            return _context.Categories.Where(p => !p.IsDelete)
                .Select(p => new ShowCategoryForAdminViewModel()
                {
                    CategoryId = p.CategoryId,
                    CategoryImageName = p.CategoryImageName,
                    CategoryTitle = p.CategoryTitle,
                    CategoryURL = p.CategoryURL,
                    CategoryMetaDescription = p.CategoryMetaDescription
                }).ToList();
        }

        public Category GetCategoryByCategoryId(int id)
        {
            return _context.Categories.Find(id);
        }

        public Category GetCategoryByCategoryTitle(string title)
        {
            return _context.Categories.SingleOrDefault(c => c.CategoryTitle == title);
        }

        public Category GetCategoryByCategoryURL(string url)
        {
            return _context.
                Categories.
                Where(c=>c.CategoryURL== "https://localhost:44374/"+url)
                .Single();
        }

        public EditCategoryForAdminViewModel GetCategoryForManageCategory(Category category)
        {
            //var categoryId = GetCategoryByCategoryId(category.CategoryId);
            //_context.Categories.SingleOrDefault(c => c.CategoryId == categoryId)
            //    .Select(p => new EditCategoryForAdminViewModel
            //    {
            //        CategoryImageName = p.
            //    });




            return null;
        }

        public bool isExistCategoryURL(string url)
        {
            return _context.Categories.Any(c => c.CategoryURL == url);
        }

        public ShowCategory ShowAllCategory(string url)
        {
            var category = GetCategoryByCategoryURL(url);
            var cat = new Category()
            {
                CategoryTitle = _context.Categories.Select(c => c.CategoryTitle == category.CategoryTitle).ToString(),
                CategoryImageName = _context.Categories.Select(c => c.CategoryImageName == category.CategoryImageName)
                    .ToString(),
                CategoryContent = _context.Categories.Select(c => c.CategoryContent == category.CategoryContent).ToString(),
                CategoryMetaDescription = _context.Categories.Select(c => c.CategoryMetaDescription == category.CategoryMetaDescription).ToString(),
                DemoFileName = _context.Categories.Select(c => c.DemoFileName == category.DemoFileName).ToString()
            };
            







            //return _context.Categories.Select(c => new ShowCategory()
            //{
            //   Category = 
            //}).ToList();
        }

        public List<ShowListCategoryViewModel> ShowAllCategoryForSideBar()
        {
            return _context.Categories.Select(
                c => new ShowListCategoryViewModel()
                {
                    CategoryTitle = c.CategoryTitle
                }).ToList();
        }

        public ShowCategoryContentViewModel ShowContentOfCategory(string url)
        {
            return _context.Categories
                .Where(c => c.CategoryURL == url)
                .Select(c=>new ShowCategoryContentViewModel()
                {
                    CategoryImageName = c.CategoryImageName,
                    CategoryContent = c.CategoryContent,
                    CategoryTitle = c.CategoryTitle,
                    DemoFile = c.DemoFileName
                })
                .Single();
        }

        public void UpdateCategory(Category category)
        {
            _context.Update(category);
            _context.SaveChanges();
        }
    }
}

标签: c#asp.net-core.net-core

解决方案


您必须创建一个包含 3 个模型的视图模型 - 1 个用于主视图,2 个模型用于局部视图

public class ViewModel
{
 public  Category Category  {get;set;}
 public List<ShowListCategoryViewModel>  ShowListCategoryViewModel {get;set;}
 public ShowCategoryContentViewModel ShowCategoryContentViewModel {get;set;}
 
}

并且您必须在主视图的操作中填写所有 3 个模型

        [Route("/{url}")]
        public IActionResult CategoryChooser(string url)
        {
            var model= new  ViewModel();
            model.Category = _categoryService.GetCategoryByCategoryURL(url);
            model.ShowCategoryContentViewModel= ShowContentOfCategory(url)
            model.ShowListCategoryViewModel= ShowAllCategoryForSideBar();
            return View(model);
        }

在此修复主视图模型之后

@model ViewModel

..... use @Model.Category for  the main view controls

......

<partial name="ListCategory", @Model.ShowListCategoryViewModel />
<partial name="CategoryContent", @Model.ShowCategoryContentViewModel/>

更新

 public Category ShowAllCategory(string url)
        {

        return    _context.Categories
                .Where(c=>c.CategoryURL== "https://localhost:44374/"+url)
                .Select(c=> = new Category
               {
                CategoryTitle = c.CategoryTitle
                CategoryImageName = c.CategoryImageName
                CategoryContent = c.CategoryContent,
                CategoryMetaDescription =  c.CategoryMetaDescription,
               DemoFileName = c.DemoFileName 
             }).FirstOrDefault();

推荐阅读