我想在我的页面上创建一个导出模型的超链接,但我不想为每个需要导出的模型编写方法。我想最终得到一个方法,可以将模型作为其中一个参数并在该模型上执行导出逻辑。 有没有办法可以将我发送到视图的模型传递回控制器操作?
修改
我有以下控制器操作 -
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 View的模型对象。 PenDaily和PenSummary都是IQueryable对象,在结果页面的表中使用。 PenDaily是主要的数据集,PenSummary用于表格页脚中的总行。
我想获取这组数据并将其导出到文件中。我有一个函数编写,但我不知道如何从我的页面使用它。我想进行设置,以便当用户点击超链接时,系统会提示他们保存导出。
如果有帮助,我的剃刀观点:
@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>
答案 0 :(得分:1)
就个人而言,我总是为视图创建单独的模型(即。GET
)或任何POSTS
。
IndexViewModel
IndexInputModel
现在的诀窍可能是利用AutoMapper
,这样您就可以更轻松地支持/维护代码,而不是拥有大量从左到右的代码(例如.foo = viewmodel.Foo)。 / p>
这个想法是这样的:你有一个在控制器中使用的基类库对象。它是主要的POCO对象。接下来,您可以看到与此POCO的架构/结构直接相关的视图模型和输入模型。使用AutoMapper(或许多从左到右的代码,如果你还是这个编程的新手),你可以轻松地“复制”相关对象之间的数据。
例如
示例视图。
视图模型。
public class IndexViewModel
{
public string Name { get; set; }
public string Description { get; set; }
public Uri InfoUrl { get; set; }
}
(查看)动作方法(错误检查等等......剥离)。
// 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);
}
..这里有一些示例Cache pseduo-code ..
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;
}
}
答案 1 :(得分:0)
将要返回的数据传递到隐藏的表单字段中,然后使用表单而不是简单的超链接将回调发送回控制器。然后它将从隐藏字段接收数据。
这是一个真正的页面状态,而不是可能与页面状态不同步的会话状态(使用后退按钮,打开另一个选项卡/窗口等)。
也就是说,如果查询价格便宜(因此速度很快),那么访问数据库并不一定是件坏事。