Mục mô hình được chuyển vào từ điển là loại .. nhưng từ điển này yêu cầu loại mục mô hình


84

Câu hỏi và câu trả lời wiki cộng đồng này đã được thêm vào để hỗ trợ việc đóng nhiều câu hỏi chưa được trả lời như đã thảo luận trong bài meta này .


Tôi có một số mã và khi nó thực thi, nó ném ra một ngoại lệ nói:

Mục mô hình được chuyển vào từ điển thuộc loại Thanh nhưng từ điển này yêu cầu mục mô hình thuộc loại Foo

Điều này có nghĩa là gì, và làm cách nào để khắc phục nó?


1
Tôi đã nhận lỗi này khi sử dụng return Viewthay vì return PartialViewđể một cái gì đó để chỉ kiểm tra
Richard Housham

Câu trả lời:


91

Lỗi có nghĩa là bạn đang điều hướng đến một chế độ xem có mô hình được khai báo là typeof Foo(bằng cách sử dụng @model Foo), nhưng bạn thực sự đã chuyển cho nó một mô hình là typeof Bar(lưu ý rằng thuật ngữ từ điển được sử dụng vì một mô hình được chuyển đến chế độ xem qua a ViewDataDictionary) .

Lỗi có thể do

Chuyển mô hình sai từ phương thức bộ điều khiển sang chế độ xem (hoặc chế độ xem một phần)

Các ví dụ phổ biến bao gồm sử dụng truy vấn tạo một đối tượng ẩn danh (hoặc tập hợp các đối tượng ẩn danh) và chuyển nó đến chế độ xem

var model = db.Foos.Select(x => new
{
    ID = x.ID,
    Name = x.Name
};
return View(model); // passes an anonymous object to a view declared with @model Foo

hoặc chuyển một bộ sưu tập các đối tượng đến một chế độ xem mong đợi một đối tượng duy nhất

var model = db.Foos.Where(x => x.ID == id);
return View(model); // passes IEnumerable<Foo> to a view declared with @model Foo

Có thể dễ dàng xác định lỗi tại thời điểm biên dịch bằng cách khai báo rõ ràng kiểu mô hình trong bộ điều khiển để khớp với mô hình trong khung nhìn hơn là sử dụng var.

Chuyển mô hình sai từ chế độ xem sang chế độ xem một phần

Cho mô hình sau

public class Foo
{
    public Bar MyBar { get; set; }
}

và một dạng xem chính được khai báo với @model Foovà một dạng xem được khai báo với @model Bar, sau đó

Foo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault();
return View(model);

sẽ trả về mô hình chính xác cho khung nhìn chính. Tuy nhiên, ngoại lệ sẽ được ném ra nếu chế độ xem bao gồm

@Html.Partial("_Bar") // or @{ Html.RenderPartial("_Bar"); }

Theo mặc định, mô hình được chuyển đến dạng xem một phần là mô hình được khai báo trong dạng xem chính và bạn cần sử dụng

@Html.Partial("_Bar", Model.MyBar) // or @{ Html.RenderPartial("_Bar", Model.MyBar); }

để chuyển thể hiện của Barsang dạng xem một phần. Cũng lưu ý rằng nếu giá trị của MyBarnull(chưa được khởi tạo), thì theo mặc định Foosẽ được chuyển cho một phần, trong trường hợp đó, nó cần phải được

@Html.Partial("_Bar", new Bar())

Khai báo một mô hình trong một bố cục

Nếu tệp bố cục bao gồm khai báo mô hình, thì tất cả các dạng xem sử dụng bố trí đó phải khai báo cùng một mô hình hoặc một mô hình dẫn xuất từ ​​mô hình đó.

Nếu bạn muốn bao gồm html cho một mô hình riêng biệt trong một Bố cục, thì trong Bố cục, hãy sử dụng @Html.Action(...)để gọi một [ChildActionOnly]phương thức khởi tạo mô hình đó và trả về dạng xem một phần cho nó.


26
+1 cho "Cũng lưu ý rằng nếu giá trị của MyBar là null (chưa được khởi tạo), thì theo mặc định Foo sẽ được chuyển cho một phần, trong trường hợp đó, nó cần phải là". Lưu ý rất quan trọng.
Smix

Tôi gặp lỗi tương tự khi có Chế độ xem một phần trong Bố cục, không có loại mô hình nào được xác định. Chế độ xem từng phần gặp sự cố vì nó nhận được mô hình từ trang chỉ mục khi không có trang nào được xác định hoặc cần thiết và nếu tôi đặt mô hình một phần thành IndexModel, thì thuộc tính ViewData là null! ?? Làm thế nào để khắc phục tình huống này? Di chuyển một phần vào bố cục hoạt động nhưng tôi muốn hiểu nó hoạt động như thế nào.
Etienne Charland

Tôi đã gặp phải lỗi tương tự khi chế độ xem một phần của tôi có "@page" ở trên cùng mà không có "@model". xóa "@page" đã giải quyết được sự cố.
EKanadily

1
Nếu bạn muốn cố tình gửi một mô hình rỗng đến xem một phần khi Model.MyBarlà null, bạn có thể làm điều này: @Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary()) Nguồn: https://stackoverflow.com/a/713921/4888725
Kirk Grover

6

Câu hỏi này đã có một câu trả lời tuyệt vời, nhưng tôi gặp phải lỗi tương tự, trong một tình huống khác: hiển thị một Listtrong một EditorTemplate .

Tôi có một mô hình như thế này:

public class Foo
{
    public string FooName { get; set; }
    public List<Bar> Bars { get; set; }
}

public class Bar
{
    public string BarName { get; set; }
}

Và đây là quan điểm chính của tôi :

@model Foo

@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })  
@Html.EditorFor(m => m.Bars)

Và đây là Bar EditorTemplate ( Bar.cshtml ) của tôi

@model List<Bar>

<div class="some-style">
    @foreach (var item in Model)
    {
        <label>@item.BarName</label>
    }
</div>

Và tôi gặp lỗi này:

Mục mô hình được chuyển vào từ điển thuộc loại 'Thanh', nhưng từ điển này yêu cầu mục mô hình thuộc loại 'System.Collections.Generic.List`1 [Thanh]


Lý do cho lỗi này là nó EditorForđã lặp lại Listcho bạn, vì vậy nếu bạn chuyển một bộ sưu tập cho nó, nó sẽ hiển thị mẫu trình chỉnh sửa một lần cho mỗi mục trong bộ sưu tập.

Đây là cách tôi khắc phục sự cố này:

Đưa các kiểu bên ngoài mẫu trình chỉnh sửa và vào chế độ xem chính :

@model Foo

@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })  
<div class="some-style">
    @Html.EditorFor(m => m.Bars)
</div>

Và đã thay đổi EditorTemplate ( Bar.cshtml ) thành thế này:

@model Bar

<label>@Model.BarName</label>

1
Tuyệt vời, bạn vừa cứu tôi sau nửa giờ vò đầu bứt tai. Cũng hoạt động cho ASP.NET Core 3.1 MVC.
Uwe Keim

5

Quan sát xem chế độ xem có mô hình được yêu cầu hay không:

Lượt xem

@model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel>

<div class="row">
    <table class="table table-striped table-hover table-width-custom">
        <thead>
            <tr>
....

Bộ điều khiển

[HttpGet]
public ActionResult ListItems()
{
    SiteStore site = new SiteStore();
    site.GetSites();

    IEnumerable<SiteViewModel> sites =
        site.SitesList.Select(s => new SiteViewModel
        {
            Id = s.Id,
            Type = s.Type
        });

    return PartialView("_ListItems", sites);
}

Trong trường hợp của tôi, tôi Sử dụng chế độ xem một phần nhưng chạy ở chế độ xem bình thường


1
Điều này có liên quan gì đến câu hỏi?

2
@StephenMuecke champs này - Mô hình mục đã qua vào từ điển là loại Bar nhưng từ điển này đòi hỏi phải có một mục mô hình của loại Foo
CelzioBR
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.