Can a Razor view have more then one model without

2020-06-14 09:23发布

问题:

@model MyMVC.Models.MyMVC.MyModel

@{
    ViewBag.Title = "Index";
}

The reason why I ask this question is in MVC we can have more than 1 form, so I would like to have a model for each form. But when I was trying to add another model at the top of the view, it displays an error. I know we can use ViewModel which has model1 and model2 inside, but it's not the question I am asking.

I just simply want to know is there any way that we can put in 2 models into 1 view.

Update:

For example, I want to have 2 forms in my view, so for each form I'd like to have a separated model.

Update 2 Thank you all for your replies. I now know that MVC only supports one single model on one view. Do you guys consider this a disadvantage of MVC? Why or Why not?(No one has answered it yet.... why?)

Your answers are similar, so I don't even know which one should be set as an answer.

回答1:

You should use some prtialviews for other models. You have your main view with main model. Inside of that view, you could have some partialviews with their models and their validations.

--------------------------------------Edit:

As others said it is better to use View Models and combine the models with each others. But as you wanted I created a sample project for you on my Github account:

https://github.com/bahman616/ASPNET_MVC_multiple_models_in_a_view_with_partialview.git

Here is the simplified code of that project:

Here are two models:

public partial class Person
{
    public int ID { get; set; }
    [Required]
    public string Name { get; set; }
}
public partial class Company
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
}

I want to have both create views in one view, so this is the parent view:

@model ASP_NET_MVC_Multiple_Models_In_A_View.Models.Person

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm("Create","Person")) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Person</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@{Html.RenderAction("_CompanyCreate", "Company");}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

And this is the partial view:

@model ASP_NET_MVC_Multiple_Models_In_A_View.Models.Company

<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@using (Html.BeginForm("_CompanyCreate","Company")) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Company</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>


回答2:

Simple answer: No, you can't have two models.

Details There is only one way to declare a Model to be used by a view:

@model [namespace].[path].[ViewModelName]

There is no way to specify multiple of these above.

In addition to that, you can only send one object to a view from the Controller, which would be the model:

public ActionResult WhateverAction()
{
    var model = new MyViewModel();
    return View(model);
}


回答3:

If you cannot/don't want to modify the model passed to the view then you could pass the additional object in via the ViewBag object. It feels like a hack to me but it works:

Controller:

ViewBag["Model2"] = yourObject

View:

@{var Model2 = ViewBag["Model2"] as yourObjectType;}


回答4:

Theoretically you cant do it because it binds one model to one view. But you can create somethink like a model helper which combines two other models to one

public class model1
{
     string var1 {get; set;}
     string var2 {get; set;}
}

public class model2
{
     string var3 {get; set;}
     string var4 {get; set;}
}

public class modelofBoth
{
     model1 mod1 {get; set;}
     model2 mod2 {get; set;}
}


回答5:

Technically, you could write your own view engine (derived from the RazorViewEngine?) using a custom WebViewPage and have it do whatever you want. The view derives from WebViewPage<T> where T is the type of the model for the page. To support multiple models, the view base class would need to have multiple generic types. Using the baked in RazorViewEngine, however, you're limited to a single model type per view and much of the controller framework presumes a single model per view so you'd have to rewrite that, too. There doesn't seem to be much point in that, however, as you could simply have your models be properties of the (single) view model, then use partial views for each of the forms providing the property as the model for the partial.

For more information see http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx



回答6:

Answer is NO. Thats why ViewModel pattern Exists. because the razor engine is totally relied on the model you passed, the model is used for ModelBinding for the basic CRUD Operations.



回答7:

You can easily have 1 model per form. For each form, you just have to do something like this:

var model = new MyModel();
@Html.TextBoxFor(m => model.Title)
@Html.ValidationMessageFor(m => model.Title)

The validation works like a charm.

This way, you can keep your model to display information as usual and have 1 model per form to submit data (for example newsletter subscription)