To create a partial view, right-click on view -> shared folder and select Add -> View option. In this way we can add a partial view. It is not mandatory to create a partial view in a shared folder but a partial view is mostly used as a reusable component, it is a good practice to put it in the "shared" folder.
In ASP.NET Core MVC, a controller's ViewResult is capable of returning either a view or a partial view. In Razor Pages, a PageModel can return a partial view represented as a PartialViewResult object. Referencing and rendering partial views is described in the Reference a partial view section.
Partial Views can use the Page Model for their data whereas Child Actions use independent data from the Controller. Editor/Display templates pass items from the model to the system but can be overridden by user partial views.
You can pass the prefix to the partial using
@Html.Partial("MyPartialView", Model.ComplexModel,
new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ComplexModel" }})
which will perpend the prefix to you controls name
attribute so that <input name="Name" ../>
will become <input name="ComplexModel.Name" ../>
and correctly bind to typeof MyViewModel
on post back
Edit
To make it a little easier, you can encapsulate this in a html helper
public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string partialViewName)
{
string name = ExpressionHelper.GetExpressionText(expression);
object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
var viewData = new ViewDataDictionary(helper.ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix) ?
name : $"{helper.ViewData.TemplateInfo.HtmlFieldPrefix}.{name}"
}
};
return helper.Partial(partialViewName, model, viewData);
}
and use it as
@Html.PartialFor(m => m.ComplexModel, "MyPartialView")
If you use tag helpers, the partial
tag helper accepts a for
attribute, which does what you expect.
<partial name="MyPartialView" for="ComplexModel" />
Using the for
attribute, rather than the typical model
attribute, will cause all of the form fields within the partial to be named with the ComplexModel.
prefix.
You can try passing the ViewModel to the partial.
@model my.path.to.namespace.MyViewModel
@Html.TextBoxFor(m => m.ComplexModel.Name)
Edit
You can create a base model and push the complex model in there and pass the based model to the partial.
public class MyViewModel :BaseModel
{
public string SomeProperty { get; set; }
}
public class MyViewModel2 :BaseModel
{
public string SomeProperty2 { get; set; }
}
public class BaseModel
{
public MyComplexModel ComplexModel { get; set; }
}
public class MyComplexModel
{
public int id { get; set; }
public string Name { get; set; }
...
}
Then your partial will be like below :
@model my.path.to.namespace.BaseModel
@Html.TextBoxFor(m => m.ComplexModel.Name)
If this is not an acceptable solution, you may have to think in terms of overriding the model binder. You can read about that here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With