System.NullReferenceException creating viewModel
本文关键字:viewModel creating NullReferenceException System | 更新日期: 2023-09-27 18:32:42
所以,我试图找到Umbraco节点(作为iPublishContent(,并将其传递给viewModel(因为Ш劫持了一条路由(。所以我把它放在我的控制器中:
private AddCouponCodesViewModel viewModel;
public AddCouponCodesController(){
//Get iPublished content
IPublishedContent content = Umbraco.TypedContent(1225);
//Pass to viewModel
viewModel = new AddCouponCodesViewModel(content);
RouteData.DataTokens["umbraco"] = content;
}
public ActionResult Index()
{
//return view etc
}
但我得到了
Exception Details: System.NullReferenceException:
Object reference not set to an instance of an object.
这里:
Source Error(AddCouponCodesViewModel.cs):
Line 20:
Line 21: }
Line 22: public AddCouponCodesViewModel(IPublishedContent content)
Line 23: : base(content)
Line 24: {
AddCouponCodeRenderModel.cs:
public class AddCouponCodesViewModel : RenderModel
{
public string test { get; set; }
public List<string> tables { get; set; }
public List<string> errors { get; set; }
public AddCouponCodesViewModel(IPublishedContent content, CultureInfo culture) : base(content, culture)
{
}
public AddCouponCodesViewModel(IPublishedContent content)
: base(content)
{
}
这是Global.asax
public class Global : UmbracoApplication
{
protected override void OnApplicationStarted(object sender, EventArgs e)
{
base.OnApplicationStarted(sender, e);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//AreaRegistration.RegisterAllAreas();
//WebApiConfig.Register(GlobalConfiguration.Configuration);
//FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
//RouteConfig.RegisterRoutes(RouteTable.Routes);
base.OnApplicationStarting(sender, e);
RouteTable.Routes.MapRoute(
"AddCouponCodes", // Route name
"Admin/{controller}/{action}/{id}", // URL with parameters
new { controller = "AddCouponCodes", action = "Index", id = "" } // Parameter defaults
);
}
}
内容已发布(我已经检查并仔细检查(,并且节点 ID 正确。
我在这里基本上要做的是获取路由 example.com/Admin/{控制器}/{操作}/{参数}要路由,但在将其与 umbracoNode 连接时遇到问题(类 RenderModel 需要一个 iPublishContent 对象作为参数,但在尝试传递它任何东西时我不走运(
有人可以在这里帮助我吗,在这个问题上被困了太多时间:-(
澄清一下,如果您劫持了一条路线,这意味着您正在覆盖 Umbraco 通过它的方式RenderModel
到它的已发布页面之一。您可以通过覆盖主RenderMvcController
来全局执行此操作,也可以基于特定于DocumentType
进行覆盖。例如,如果我有一个主页文档类型,我可以创建:
public HomepageController : RenderMvcController
{
public override ActionResult Index(RenderModel model)
{
// Create your new renderModel here, inheriting
// from RenderModel
return CurrentTemplate(renderModel);
}
}
这将通过这一个操作将所有调用路由到主页。为此,您无需在路由表中定义任何新路由。并且您应该在操作中而不是在构造函数中重写渲染模型。
您的问题有点令人困惑,并且不完全清楚您要实现的目标,因为:
- 您已经定义了一条路由,并且
- 在构造函数中,您调用
Umbraco.TypedContent(1225)
来检索特定的已发布节点
所以。。。如果您尝试路由的管理页面本身已由 Umbraco 发布(听起来不像是这样(,只需创建一个具有页面文档类型名称的新控制器,并以上述方式覆盖渲染模型。
然而。。。如果您的管理页面尚未由 Umbraco 发布,并且您只希望管理页面访问节点数据,那么您有几个选择:
- 创建从 SurfaceController 继承的曲面控制器。这将使您能够访问 Umbraco 上下文等;或
- 创建一个标准控制器(最好在区域中(并使用类似 Autofac 的东西注入
ContentCache
例如:
builder.RegisterControllers(typeof (AdminController).Assembly)
.WithParameter("contentCache", UmbracoContext.Current.ContentCache);
- 创建一个标准控制器(最好在一个区域中(并使用 Umbraco 的
ContentService
API 访问节点,即new Umbraco.Core.Services.ContentService().GetById(1225)
最后两种方法之间的区别在于:
- 注入
ContentCache
为您提供对已发布内容的只读但非常快速的访问。 - 访问
ContentService
为您提供对节点本身的读/写访问权限,但以牺牲速度为代价,因为您直接查询数据库。
这取决于您的要求是什么。
无论哪种方式,都值得花时间通读有关劫持Umbraco路由的文档,至少尝试了解正在发生的事情。
好吧,我可以告诉你,你的视图没有得到任何关于 Razor 标记的信息,因为你的 Index 方法没有给它任何东西。 这是一个问题。 我还可以告诉你,在你的AddCouponCodesViewModel中,你需要一个空的构造函数,以便剃刀语法可以创建一个实例,然后填充它以将你提交的对象与视图相匹配。
修改您的视图控制器:
public ActionResult Index()
{
return View(viewModel);
}
修改 AddCouponCodesViewModel 以添加一个 Empty 构造函数:
public AddCouponCodesViewModel()
{
}
在视图模型上创建一个无参数构造函数,如下所示:
public AddCouponCodesViewModel():
this(new UmbracoHelper(UmbracoContext.Current).
TypedContent(UmbracoContext.Current.PageId))
{
}
这将获取其他构造函数正在寻找的上下文。创建具有特定构造函数的类后,编译器默认停止生成无参数类。由于您需要一个无参数构造函数,因此这就是获取一个并且仍然传递视图模型所需的 Umbraco 上下文信息