andre
andre

Reputation: 1680

Using dynamic models in partials using Razor syntax is throwing an error

I will be using the same partial across many different pages and the only thing that will be different is reference to the model (@model ...). I tried using "@model dynamic" so I can reference model in view, however lambdas that are in my partial that are referencing specific properties are throwing the following error:

"An expression tree may not contain a dynamic operation"

caused by the following reference to model:

@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })

How do structure my code or create a model reference that will work dynamically so that I can reference each specific model instance in my view pages? I tried many solutions online and nothing has worked so far. Below is my partial and view. Any help would be greatly appreciated!!!

Partial:

@model dynamic

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="container creative-containter-top">
    <div class="row">
        <div class="col-sm-offset-2 col-sm-8">
            <div class="form-horizontal">
                <div class="panel panel-primary">
                    <div class="panel-height pane panel-heading text-center">
                        <h3>@ViewBag.Title</h3>
                    </div>
                    <div class="panel-body">
                        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                        @Html.HiddenFor(model => model.Id)

                        <div class="form-group">
                            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                            <div class="col-md-10">
                                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            @Html.LabelFor(model => model.Code, htmlAttributes: new { @class = "control-label col-md-2" })
                            <div class="col-md-10">
                                @Html.EditorFor(model => model.Code, new { htmlAttributes = new { @class = "form-control" } })
                                @Html.ValidationMessageFor(model => model.Code, "", new { @class = "text-danger" })
                            </div>
                        </div>

                       <div class="form-group">
                            @Html.LabelFor(model => model.Code, htmlAttributes: new { @class = "control-label col-md-2" })
                            <div class="col-md-10">
                                @Html.EditorFor(model => model.Code, new { htmlAttributes = new { @class = "checkbox center-block" } })
                                @Html.ValidationMessageFor(model => model.Code, "", new { @class = "text-danger" })
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <input type="submit" value="Save" class="btn btn-primary" />
                            </div>
                        </div>
                    </div>

                    <div class="panel-footer">
                        @Html.ActionLink("Back to List", "Index")
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
}

View

@model CreativeNamingConvention.Models.Domain.CreativeOps

@{
ViewBag.Model = Model;
ViewBag.Title = "Edit Creative Ops Field";
}

@Html.Partial("~/Views/Templates/editBody.cshtml", Model)

Upvotes: 0

Views: 969

Answers (3)

andre
andre

Reputation: 1680

I figured out a simple approach if you are ok with basic css and nothing fancy.

You can use "EditForModel()" to display all of the properties in your model instead of "EditFor" each property. After this, for each property that you do not want to have displayed in your view, you can add "[ScaffoldColumn(false)]" in the model as shown below. Thanks for all the advice!!!

Partial

@model dynamic

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="container creative-containter-top">
    <div class="row">
        <div class="col-sm-offset-4 col-sm-4">
            <div class="form-horizontal">
                <div class="panel panel-primary">
                    <div class="panel-height pane panel-heading text-center">
                        <h3>@ViewBag.Title</h3>
                    </div>
                    <div class="panel-body">
                        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

                        <div class="col-sm-offset-2">
                            <div class="form-group">
                                @Html.EditorForModel()
                            </div>
                        </div>
                                <div class="form-group">
                                    <div class="col-md-offset-2 col-md-10">
                                        <input type="submit" value="Save" class="btn btn-primary" />
                                    </div>
                                </div>
                            </div>

                            <div class="panel-footer">
                                @Html.ActionLink("Back to List", "Index")
                            </div>
                        </div>
                    </div>
        </div>
    </div>
</div>
}

Model

 public partial class CreativeOps
 {
    public CreativeOps()
    {
        CreativeNames = new HashSet<CreativeNames>();
    }
    [ScaffoldColumn(false)]
    public int Id { get; set; }
    [Required]
    public string Code { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public bool Disabled { get; set; }

    public virtual ICollection<CreativeNames> CreativeNames { get; set; }
}
}

Upvotes: 0

Brian Mains
Brian Mains

Reputation: 50728

Based on that message, I assume that you can't use the "For" suffixed methods with dynamic operations.

Never used them, but you could try the generic form:

@Html.Label("Name", "Name Label", htmlAttributes: new { @class = "control-label col-md-2" })

The syntax says expression, so I assume it would support dot notation.

Upvotes: 0

Midhun Mundayadan
Midhun Mundayadan

Reputation: 3192

check null from your action method or razor view

dynamic keyword in C# 4.0 allows you to do a dynamic model binding

  dynamic viewModel = new ExpandoObject();
  viewModel.TestString = "This is a test string";

 return View(viewModel); for more in refer the below link

examles

Dynamic model binding with examle

Upvotes: 0

Related Questions