Asp-MVC的最佳做法,用于在ViewModel中填充查找值

我有一个带有一个创建表单的小型Web MVC虚拟应用程序(使用ViewModel)。视图模型具有有界值和无界值(例如,查找)。但是首先您可以在下面看到我的示例代码:

/// <summary>
/// I'm the model from persistence layer.
/// </summary>
public class Product
{
    public Product()
    {
    }
    public Product(int id,string name)
    {
        Id = id;
        Name = name;
    }

    public int Id { get; set; }
    public string Name { get; set; }
}

/// <summary>
/// I am optimized for view.
/// You can give me a name and select a product.
/// </summary>
public class DummyViewModel
{
    [microsoft.AspNetCore.Mvc.HiddenInput()]
    public int Id { get; set; }
    public string Name { get; set; }

    public int ProductId { get; set; }
    public IEnumerable<SelectListItem> ProductLookup { get; set; }
}
public class DummyController : Controller
{
    [HttpGet]
    public IactionResult Create()
    {
        var dummyViewModel = new DummyViewModel()
        {
            Name = "New Dummy",};
        UpdateLookupsOnViewModel(dummyViewModel);

        return View(dummyViewModel);
    }

    /// <summary>
    /// I'm the pingback action-method if client has filled the create form.
    /// If given viewmodel is invalid or if saving failes 
    /// the given viewmodel will be returned.
    /// If that happens then it will loose all the lookups.
    /// So they must be updated again in that two cases.
    /// </summary>
    [HttpPost]
    public IactionResult Create(DummyViewModel vm)
    {
        if (vm == null || !ModelState.IsValid)
        {
            // 1. Given viewmodel is invalid,so update the lookups.
            UpdateLookupsOnViewModel(vm);
            return View(vm);
        }

        try
        {
            // Save into repo.
            throw new Exception("Dummy exception,which simulates an error while saving.");

            return Redirect("stackoverflow.com");
        }
        catch
        {
            // 2. Saving failed,so update the lookups.
            UpdateLookupsOnViewModel(vm);
            return View(vm);
        }
    }

    private void UpdateLookupsOnViewModel(DummyViewModel vm)
    {
        if (vm is null)
        {
            throw new ArgumentNullException(nameof(vm));
        }

        vm.ProductLookup = GetProductsFromRepository()
            .Select(o => new SelectListItem(o.Name,o.Id.ToString()));
    }

    /// <summary>
    /// I simulate the access to database.
    /// </summary>
    private IEnumerable<Product> GetProductsFromRepository()
    {
        return new[]
        {
            new Product(1,"My Product"),new Product(2,"BB Super"),new Product(3,"Jooooe"),new Product(4,"Igel"),};
    }
}

下面您可以看到ASP-HTML-View

@using Experiment.Web.ViewModels

@model DummyViewModel

<form asp-action="Create">
    <input asp-for="Id"/>

    <div>
        <label asp-for="Name" class="control-label"></label>
        <div class="div-input-aussen"><input asp-for="Name" class="form-control"/></div>
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>

    <div>
        <label asp-for="ProductLookup" class="control-label"></label>
        <div><select asp-for="ProductId" asp-items="@Model.ProductLookup" class="form-control"></select></div>
        <span asp-validation-for="ProductLookup" class="text-danger"></span>
    </div>

    <input type="submit" value="Speichern"/>
</form>

您可以在注释中阅读我的问题,但总而言之:viewmodel( ProductLookup )中的无边界值。

如果客户端使用HTTP-Get请求创建表单,则会创建一个新的 DummyViewModel 。如果他填写了所有必需的值,则使用HTTP-POST并将DummyViewModel发送到Controller action。 如果控制器操作检测到给定的视图模型无效或保存过程失败,他会将给定的视图模型发送回客户端。 如果发生这种情况,所有无边界的值都会丢失,因此必须在视图模型上再次对其进行更新。

我的查找值存储在数据库中(在实际应用中)。因此可能是性能问题。

现在我想知道其他人如何处理这种情况。您是否使用缓存?当我忘记在返回之前调用 UpdateLookupsOnViewModel 时该怎么办? 您是否有帮助或某些模式的编码风格?

感谢您的阅读!

a15116337758 回答:Asp-MVC的最佳做法,用于在ViewModel中填充查找值

我认为没有最佳实践,只是方法不同。

我个人认为您的UpdateLookupsOnViewModel方法是可行的方法;但是如果担心存储库中的I / O性能,则可以使用TempDataSession将值保留在内存中。另一种方法是将值存储在隐藏字段中(例如,以JSON或分隔字符串的形式),然后将其回发并重建列表。

不幸的是,HTTP是无状态的,因此这些只是模仿应用程序中状态的不同方式。

,

在谈论网络时,我调用一种方法来两次填充查询:一种用于GET(通常),另一种用于“ exceptions”(POST-无效的提交数据,依此类推)。但是,由于我一直都在访问数据库,因此这会降低性能。

我找到的解决方法是cache the lookup in memory。但是,您需要考虑使用哪种查找数据(更改频率,更改大小,应在缓存中保留多长时间等),以定义缓存策略。

我缓存的一般规则是使用不同的缓存键(“ cache_prod”,“ cache_prod_type”)将所有查找分隔开,这样您就只能重建发生时更改的内容。

您可能可以执行以下操作:

private void UpdateLookupsOnViewModel(DummyViewModel vm)
{
    if (vm is null)
    {
        throw new ArgumentNullException(nameof(vm));
    }

    vm.ProductLookup = GetProductFromCache("cache_product");
}

方法GetProductFromCache可能大致如下:

private Product GetProductFromCache(string cacheKey)
{
    IMemoryCache _memoryCache;
    Product product;
    if (!_memoryCache.TryGetValue(cacheKey,out product))
    {
        product = GetProductsFromRepository()
                    .Select(o => new SelectListItem(o.Name,o.Id.ToString()));
    }

    return product;
}
本文链接:https://www.f2er.com/3109232.html

大家都在问