【问题标题】:Partial View uses different model than page it's contained in?部分视图使用的模型与其包含的页面不同?
【发布时间】:2014-07-23 02:27:21
【问题描述】:

我的主页中有一个局部视图,它使用的模型与主页使用的不同。

简而言之,我的主页上有一个下拉控件,它使用一个模型来填充其选项。当一个选项被选中时,我有一个脚本会将所选选项发布到家庭控制器中的另一个操作方法。该方法采用该值,并根据该值运行数据库查询。然后我将这些结果放入一个模型并将该模型传递给我的局部视图。呈现局部视图,然后将其转换为 HTML 标记并以 JSON 对象的形式传回脚本。然后脚本将生成的视图标记写入主页中的 div。

我的问题是我收到一条错误消息,指出局部视图正在寻找一个模型,而它获取的模型是主页的模型,而不是它自己的模型。有没有一种简单的方法可以解决这个问题?我不能将两个模型包装在另一个模型(视图模型)中,因为这两个模型通过不同的操作方法传递。

以下是希望提供帮助的相关代码:

控制器

public class HomeController : Controller
{
    // Loaded when page first requested. Displays a dropdown with all
    // distinct sampling events.
    public ActionResult Index()
    {
        // Set page title
        ViewBag.Title = "Sample Tracker Tool";
        // Calculate range filter for samples
        DateTime nineMonthsAgo = DateTime.Now.AddDays(-270);

        // Retrieve sampling events within filter range
        var context = new EDMS_Entities();
        var resultSet = (from samplingEvents in context.EDMS_SAMPLES
                         where samplingEvents.RECORD_CREATED_DATE >= nineMonthsAgo
                         orderby samplingEvents.SAMPLING_EVENT
                         select samplingEvents.SAMPLING_EVENT).Distinct();

        // Create viewmodel for sampling events dropdown use
        var viewModel = new SamplingEventsVM();
        viewModel.SamplingEvents = new SelectList(resultSet);

        return View(viewModel);
    }

    // When the selected sampling event is changed, jQuery posts the selected value
    // to this method. The selected value is used to return all samples for the
    // selected sampling event.
    public ActionResult RetrieveSamples(string samplingEvent)
    {
        // This currently just returns the selected sampling event
        // TODO: Use sampling event to retrieve all samples and construct a list of
        // Sample objects for the selected sampling event. These samples will be used
        // to display the sample's list of analytes.

        // Retrieve samples for selected sampling event
        // **Samples query in progress...**
        // TODO: Finish constructing the full query
        var context = new EDMS_Entities();
        var resultSet = from samples in context.EDMS_SAMPLES
                        join stations in context.EDMS_SAMPLE_STATIONS on samples.STATION_SEQ equals stations.STATION_SEQ
                        where samples.SAMPLING_EVENT == samplingEvent
                        select new { samples.SAMPLE_ID, stations.STATION_ID, samples.COLLECTION_DATE, samples.COMMENTS };

        // Assign results to model objects and add resulting model objects to the ObservableCollection instance "sampleResults"
        ObservableCollection<Sample> sampleResults = new ObservableCollection<Sample>();
        foreach(var row in resultSet)
        {
            var newSample = new Sample(row.SAMPLE_ID, row.STATION_ID, row.COLLECTION_DATE, row.COMMENTS);
            sampleResults.Add(newSample);
        }

        // Pass sample objects to partial view and parse HTML markup from rendered partial view
        var partialViewHtml = RenderViewToString(this.ControllerContext, "~/Views/Home/RetrieveSamples.cshtml", sampleResults);

        // Add partial view HTML markup to new JsonResult object
        JsonResult result = new JsonResult();
        result.Data = partialViewHtml;

        return result;
    }

    // Convert partial view to HTML string
    private string RenderViewToString(ControllerContext context, string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
        {
            viewName = context.RouteData.GetRequiredString("action");
        }

        var viewData = new ViewDataDictionary(model);

        using (var writer = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
            var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), writer);
            viewResult.View.Render(viewContext, writer);

            return writer.GetStringBuilder().ToString();
        }
    }
}

主视图

<!DOCTYPE html>

<html>
    @using SampleTracking.Models.ViewModels;
    @model SamplingEventsVM
    <head>
        <title>@ViewBag.Title</title>
        <script src="~/Scripts/jquery-2.1.1.js"></script>
        <script type="text/javascript" src="~/Scripts/CustomScripts.js"></script>        
    </head>
    <body>
        <span id="SamplingEventDiv">
            @Html.DropDownListFor(model => model.SelectedSamplingEvent, Model.SamplingEvents, new { @id = "SamplingEventSelection" })
        </span>
        <div id="SamplingEventDetails">
            @Html.Partial("~/Views/Home/RetrieveSamples.cshtml")
        </div>
    </body>
</html>

局部视图

@using System.Collections.ObjectModel;
@using SampleTracking.Models.ViewModels;
@model ObservableCollection<Sample>
<div id="SamplingEventDetails">
    @foreach (var sample in Model)
    {
        <div>sample.SampleID</div>
    }
</div>

【问题讨论】:

    标签: jquery asp.net-mvc model viewmodel partial-views


    【解决方案1】:

    你试过了吗……

    Html.Partial("~/Views/Home/RetrieveSamples.cshtml",new SomeModel())
    

    【讨论】:

    • 我没有,但我会试一试。
    • 其实现在我想起来了,我认为这并不能解决我的问题。那条线仍在主视图中,所以我必须以某种方式将模型放在那里,这是我的问题。
    【解决方案2】:

    所以我认为我解决了这个问题——结果我真的不需要 Html.Partial,因为我的脚本无论如何都会将呈现的视图作为 HTML 获取。辅助方法是不必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 2013-06-18
      • 2019-05-30
      相关资源
      最近更新 更多