0

我想在我的页面上创建一个超链接来导出我的模型,但我不想为我需要导出的每个模型编写一个方法。我想最终得到一种可以将模型作为其参数之一并在该模型上执行导出逻辑的方法。有没有一种方法可以将发送到视图的模型传递回控制器操作?

编辑:

我有以下控制器动作-

    public ViewResult PenDaily(Nullable<DateTime> startDate = null, Nullable<DateTime> endDate = null, string listName = "")
    {
        //Removed code for brevity/clarity

        PenDailyViewModel penDailyView = new PenDailyViewModel();
        penDailyView.startDate = startDate;
        penDailyView.endDate = endDate;
        penDailyView.listNames = GetLists(m_db);
        penDailyView.penDaily = GeneratePenDaily(m_db, listName, startDate, endDate);
        penDailyView.penSummary = GeneratePenSummary(m_db, startDate, endDate, "").Where(a => a.listName == listName);

        return View(penDailyView);
    }

PenDailyViewModel 是我传递给我的 Razor 视图的模型对象。PenDaily 和 PenSummary 都是 IQueryable 对象,在结果页面上的表中使用。PenDaily 是主要数据集,PenSummary 用于表格页脚中的总行。

我想获取这组数据并将其导出到文件中。我有一个为此编写的函数,但我不知道如何从我的页面中使用它。我想进行设置,以便当用户单击超链接时,系统会提示他们保存导出。

如果有帮助,我的 Razor 观点:

@model WebTools.Models.PenDailyViewModel

<table>
    <thead>Header Stuff</thead>
    <tbody>
    @foreach (var item in Model.penDaily)
    {
        //Generate table body
    }
    </tbody>
    <tfoot>
    @foreach (var item in Model.penSummary)
    {
        //Generate table footer
    }
    </tfoot>
</table>
4

2 回答 2

1

就个人而言,我总是为视图(即 a GET)或任何POSTS.

  • IndexViewModel
  • IndexInputModel

很多时候,这些 poco 非常相似。

现在的诀窍可能是利用AutoMapper,这样您就可以更容易地支持/维护您的代码,而不是拥有大量从左到右的代码(例如 foo = viewmodel.Foo)。

这个想法是这样的:你有一个在控制器中使用的基类库对象。它是主要的 POCO 对象。接下来,您将拥有与此 POCO 的架构/结构直接相关的视图模型和输入模型。使用 AutoMapper(或大量从左到右的代码,如果您对这种编程内容还不熟悉),您可以轻松地在相关对象之间“复制”数据。

例如。

示例视图。

视图模型。

public class IndexViewModel
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Uri InfoUrl { get; set; }
}

(View) Action 方法(错误检查等。被剥离)。

// product/{id}   eg /products/5
public Action Index()
{
    // Load the Product.
    var product = YourRepository.Load(id);
    if (product == null)
    {
        return NotFound("Product can't be found.");
    }

    // Convert the product to this view requirements.
    // This will copy over the Name and the Uri.
    var model = Mapper.Map<Product, IndexViewModel>(product);

    return View(model);
}

这里的必要条件是该 ONE 视图的模型有一个硬且清晰的表示。每个视图都应该有自己的模型,因为每个视图都是独一无二的。

现在你可能会说“我不想要两个模型”。好吧,我建议你这样做。事实上,这里有 3 个模型。主要用于控制器/服务/业务逻辑。另外两个用于输入(可选)或视图(每个操作都需要某种类型的结果)。

更新

你说你想避免多次去数据库。公平通话!:) 诀窍是利用CACHING代替。不将数据存储在客户端?为什么?首先,我可以在 1 秒内破解客户端数据。第二缓存(通常)便宜且(通常)非常快。

让我们更新初始代码...

// product/{id}   eg /products/5
public Action Index()
{
    // Load the Product from your cache
    var product = YourCache.Load(id);
    if (product == null)
    {
        return NotFound("Product can't be found.");
    }

    // Convert the product to this view requirements.
    // This will copy over the Name and the Uri.
    var model = Mapper.Map<Product, IndexViewModel>(product);

    return View(model);
}

..这是一些示例缓存伪代码..

public class YourCache
{
    private static ObjectCache cache = MemoryCache.Default; 

    private IRepository Repository { get; set; }

    public YourCache(IRepository repository)
    {
        Repository = repository;
    }

    public Product Load(int id)
    {
        var product = cache["Product-" + id] as Product;
        if (product == null)
        {
            // Grab it and remember it.
            product = repository.Load(id);

            if (product != null)
            {
                cache.Set("Product-" + id, product, ....);
            }
        }

        return product;
    }
}
于 2012-09-16T23:34:38.933 回答
0

在隐藏的表单字段中传递您想要返回的数据,然后使用表单而不是简单的超链接来调用您的控制器。然后它将接收来自隐藏字段的数据。

这是一个真正的页面状态,而不是可能与页面状态不同步的会话状态(使用后退按钮、打开另一个选项卡/窗口等)。

也就是说,如果查询便宜(因此很快),访问数据库不一定是坏事。

于 2012-09-16T23:28:56.390 回答