Now I have a controller:
public async Task<IActionResult> Location()
{
Models.LocationModel Location = null;
//some logic
return View(Location);
}
And here is the View:
@model Vishdo.Models.LocationModel
<div>
<h5>@Model.City</h5>
<span>@Model.Name</span>
<span>@Model.Phone</span>
</div>
When I access the View by the URL(https://localhost:44372/home/location) directly, all works well.
Now I add it into the _Layout.cshtml
like this:
@Html.PartialAsync("/Views/Home/Location.cshtml")
After it ran, it reports an error on the View Location.cshtml
:
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Sample.Views
StackTrace:
at AspNetCore.Views_Home_Location.<ExecuteAsync>d__0.MoveNext() in E:\Project\Sample\Views\Home\Location.cshtml:line 3
I added a breakpoint in the Location controller and found it never works. So the Model always is null and reports this error.
In addition, I add this into the _Layout.cshtml
for this feature is needed by all the pages and the _Layout.cshml
has not a controller so I have to do it like this.
What's wrong with my code? How can I solve it? Thank you.
I added a breakpoint in the Location controller and found it never works. So the Model always is null and reports this error.
It's the expected behavior, @Html.PartialAsync()
will not trigger the controller action, it directly search the partival view under the view folder.
In addition, you can achieve it with ViewComponent
. I made a demo like below:
1.Create a folder named ViewComponents
in your project, and create a class named LocationViewComponent
public class LocationViewComponent : ViewComponent
{
public IViewComponentResult Invoke()
{
var Location = new LocationModel()
{
City = "AAA",
Name = "BBB",
Phone = "CCC"
};
return View(Location);
}
}
2.The default view name for a view component is Default.cshtml, add it to the Shared folder like below:
Default.cshtml
@model LocationModel
<div>
<h5>@Model.City</h5>
<span>@Model.Name</span>
<span>@Model.Phone</span>
</div>
3.Call the ViewComponent in the layout:
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
@await Component.InvokeAsync("Location")
</main>
</div>
Result:
For more details, you can refer to the document
Since @Html.PartialAsync() will not trigger the controller action so you've multiple options here to solve your problem.
1- you should get the Location model from any service and pass it to @Html.PartialAsync() like below:
@inject LocationService locationService
@{
var locationModel = locationService.GetLocation();
}
and then pass this locationModel to @Html.PartialAsync()
@Html.PartialAsync("/Views/Home/Location.cshtml", locationModel );
User contributions licensed under CC BY-SA 3.0