InvalidOperationException在强类型视图中呈现ViewComponent [英] InvalidOperationException rendering ViewComponent in Strongly-Typed View

查看:1192
本文介绍了InvalidOperationException在强类型视图中呈现ViewComponent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近更新的dotnet核心1.0.1至1.1和MVC中的ViewComponent开始失败,并出现以下异常:

Recently updated dotnet core 1.0.1 to 1.1 and ViewComponent in MVC starts failing with the below exception:

InvalidOperationException: One or more errors occurred. (The model item passed into the ViewDataDictionary is of type 'App.Models.HomeViewModel', but this ViewDataDictionary instance requires a model item of type 'App.Components.LoginViewComponent'.)

Index.cshtml 呈现 LoginViewComponent

@model App.Models.HomeViewModel
<html>
   @Component.InvokeAsync("LoginViewComponent")
</html>

视图/主页/Index.cshtml

ViewComponent LoginViewComponent / Default.cshtml 只是一个显示模型信息的类:

The ViewComponent LoginViewComponent/Default.cshtml is just a class that displays it's model's info:

@model App.Components.LoginViewCompoent
<body>
    <div>@Html.DisplayFor(v=>v.LoginName)</div>
</body>

视图/共享/组件/LoginViewComponent/Default.cshtml

当从 Default.cshtml 中删除 @model 指令时,它会很好显示。

It renders fine when the @model directives is removed from Default.cshtml.

ViewComponent是否应该与包装它的父视图分离且不可知?从例外来看,似乎需要在 HomeViewModel 类中声明 LoginViewComponent ViewComponent才能进行渲染。

Isn't ViewComponent suppose to be separated and agnostic from the parent view that is wrapping it? From the exception it seems that it would be require to declare the LoginViewComponent ViewComponent in HomeViewModel class in order to render it.

在asp.net核心github上找不到任何更改说明。

Couldn't find any change note on this on asp.net core github.

评论并提供帮助

推荐答案

我遇到了相同的错误,我团队中的某人更新了 Microsoft.AspNetCore.Mvc 版本从1.0.0到1.1.0,我在Strongly-Type视图中拥有的某些组件开始抛出

I've came across the same error, someone in my team updated Microsoft.AspNetCore.Mvc version from 1.0.0 to 1.1.0 and some of the components I had in Strongly-Type views started throwing


InvalidOperationException:传递到ViewDataDictionary的模型项的类型为'My.StronglyView.ObjectType',但是此ViewDataDictionary实例需要类型为'My的模型项.ViewComponent.ObjectType'

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'My.StronglyView.ObjectType', but this ViewDataDictionary instance requires a model item of type 'My.ViewComponent.ObjectType'.

我不确定此更改是否是有意的,但绝对不是我们要做的

I am not sure if this change was intentional, but it is definitely not what we would expect.

我没有时间研究这种突破性变化的原因,但我提供了解决方案。

I haven't got the time to research about the reasons of this 'breaking' change but I came with a solution.

是的,如果将空对象传递给y我们的 ViewComponent.View()方法,我们得到了这个异常。通过它传递的任何非空对象都将更新ViewData.ModelExplorer,并且将注册正确的 object-type ,避免出现此异常。

Thing is, if you pass a null object to your ViewComponent.View() method, we get this exception. Any non-null object passed through it, would update the ViewData.ModelExplorer and the correct object-type would have been registered, avoiding this exception.

使用Tester-Doer模式,与.Net Framework某些类中使用的模式相同,我们现在可以将非null对象传递给 ViewComponent 并使用它及其包装的

Using Tester-Doer pattern, same pattern used in some classes of .Net Framework, We can now pass a non-null object to the ViewComponent and use it and its wrapped object as We need.

我所做的是,我创建了一个接口 IViewComponentModel< T> 作为类 ViewComponentModel< T> 如下:

What I did was, I created a interface IViewComponentModel<T> as class ViewComponentModel<T> as below:

// Interface for ViewComponentModel
public interface IViewComponentModel<T> 
    where T : class
{
    T Data { get; }
    bool HasData();
}

// ViewComponentModel class for the Strongly-Type View Component
public class ViewComponentModel<T> : IViewComponentModel<T>
    where T : class
{
    public T Data { get; private set; }

    public ViewComponentModel(T data)
    {
        Data = data;
    }

    public bool HasData() => Data != null;
}

在ViewComponent类的实现中,我返回 View( new ViewComponentModel< AnyReferenceType>(myModel));

In my ViewComponent class implementation, I return View(new ViewComponentModel<AnyReferenceType>(myModel));

public async Task<IViewComponentResult> InvokeAsync()
{
    var myViewData = _myService.GetSomeObjectForMyViewComponent();
    var model = new ViewComponentModel<MyViewDataType>(myViewData);

    return await Task.FromResult(View(model));
}

最后,在我的组件视图(.cshtml)中,我有以下代码:

And finally, in my Component View (.cshtml) I have the code below:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model ViewComponentModel<MyViewDataType>

现在,您可以在视图内部对该对象进行任何操作,并使用真实模型,只需调用 @ Model.Data 即可。

Now you can do whatever you want with this object inside of the view and to use your real model, just call @Model.Data and voilà.

通过这种方式,我们绝不会将空对象传递给ViewComponent,也不会从继承视图中继承对象类型。

In this way, We will never pass a null object to the ViewComponent and it won't 'inherit' the object type from the View.

希望有帮助!

这篇关于InvalidOperationException在强类型视图中呈现ViewComponent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆