aspnet / Mvc

[Archived] ASP.NET Core MVC is a model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
5.62k stars 2.14k forks source link

ViewComponent ViewData #8580

Closed Eilon closed 5 years ago

Eilon commented 5 years ago

From @csutorasr on Wednesday, 10 October 2018 00:13:50

MVC and Razor Pages: https://github.com/aspnet/Mvc

I tried to create a ViewComponent and try to use ViewData from it.

The ViewComponents are using different ViewContext from the page that executed it. This way I can't reach or set ViewData, that can be later passed to layout of the page.

I managed to reach the data of the parent with an ugly solution, while I kept trying:

(Component as IViewContextAware)?.Contextualize(ViewContext);

This way the ViewComponent could reach data from the page that invoked it, but the other way of the data cannot be made, because of the new context.

You could ask why I need ViewData in ViewComponent.

I am creating a "lot" (I hope it will be a lot) of libraries to make it easier to create a CMS system with ASP.NET Core. The only reference in my code is the MVC and EF, and I try to keep it for later. This way any project using MVC needs some CMS functionality, that can be inserted in no time without affecting the structure of the original project (only some entities in EF).

I needed a way to show views if I get a contentId. I would like to use the higher abstraction levels of the framework as changing less frequently.

  1. Pages with rewrite middleware was my first solution but those can be reached with the original URL too.
  2. ViewComponent seemed the best solution, but I couldn't set the ViewData.

If there's any other options that with I can solve this problem please tell me.

Copied from original issue: aspnet/AspNetCore#3604

mkArtakMSFT commented 5 years ago

Thanks for contacting us, @csutorasr. @pranavkm, can you please look into this? Thanks!

mkArtakMSFT commented 5 years ago

Not sure this one is related or not: https://github.com/aspnet/Mvc/issues/7675

csutorasr commented 5 years ago

Thank you for your kindness.

https://github.com/aspnet/Mvc/commit/b62499e02c274db162151556318b0a5fae85360e#diff-25d98c04d15f91552e80a30fdd460174R99

I think this line in this commit solved the problem. I have seen it in the Razor pages code, but not in the viewcomponent.

Lines that I found where data comes from:

I think if there is any more result executor all of them should be fixed.

mkArtakMSFT commented 5 years ago

@pranavkm, can you please see whether it makes sense to extend the fix to the above mentioned areas? Thanks!

csutorasr commented 5 years ago

I wrote a test that should not fail. You can find it here: https://github.com/csutorasr/Mvc/commit/f2e9fd9095eac6a3b560720d6f7714e462710c12 .

The text is written as it should be, but the data is not set. I would not make a PR as there is no solution in the commit.

pranavkm commented 5 years ago

This behavior is by design. Partials and ViewComponents get a separate copy of ViewData and changing this behavior would be a breaking change. There are a couple of suggestions on StackOverflow (e.g. https://stackoverflow.com/a/43829111) that suggest ways to pass data around between view components and other Razor files.