'Pass parameter to Partial View in ASP.NET Core

On an ASP.NET Core 2.0 application I need to render a partial view and pass a few parameters:

@Html.Partial("Form", new { File = "file.pdf" })

On the partial view I tried to access it using:

@Model.File

And I get the error:

RuntimeBinderException: 'object' does not contain a definition for 'File'

If I simply use on my partial:

@Model

I get the following printed on the page:

{ File = file.pdf } 

So there the model is being passed and there is a property File in it.

So what am I missing?



Solution 1:[1]

You are passing untyped (anonymous type) data to partial view. You cannot use @Model.File. Instead, you will need to use ViewData's Eval method to retrieve the value.

@ViewData.Eval("File")

Traditional approach is to create a strongly typed ViewModel class, and pass it to the partial view. Then you can access it as @Model.File.

public class SampleViewModel
{
    public string File { get; set; }
}

@Html.Partial("Form", new SampleViewModel { File = "file.pdf" })

Inside Partial View,

@model SampleViewModel

<h1>@Model.File</h1>

Solution 2:[2]

You should have dynamic as the model of your partial view, this way, you can pass everything - like your anonymous object - and it will just work. Add:

@model dynamic

To the Form.cshtml file.

Solution 3:[3]

When you do new { File = "file.pdf" }, you are passing an object that contains an attribute file. Since this is of type object, you can't access any of its variables in c# directly. There some ugly codes to access a fields from an object such as the one that can be found here: C# .NET CORE how to get the value of a custom attribute?

However in this case the most recommended way (for safety) is the create a class and pass an object of that class.

So if you create the following class:

public class MyFileInfo{
    public string File { get; set }
}

Then you can create your object by passing:

@Html.Partial("Form", new MyFileInfo{ File = "file.pdf" })

In your partial view, at the beginning, define your model class

@model MyFileInfo

Then in the same file you will now be able to access

@Model.File

Solution 4:[4]

For the sake of completeness: you can pass arbitrary variable via a ViewDictionary

@Html.Partial("_Partial", model, new ViewDataDictionary(ViewData) { { "MyVarName", someValue } })

And then access it like this in the partial:

ViewData["MyVarName"]

Another option, you can simply set a ViewData var before calling the partial, and it will be passed on to it

@{
    ViewData["MyVarName"] = "hello";
}
@Html.Partial("_Partial", model)

However, strongly typed models are much easier to work with.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ricardo Peres
Solution 3 Neville Nazerane
Solution 4