我应该在控制器中使用常规方法吗?

时间:2017-05-03 14:24:33

标签: c# asp.net-mvc

所以基本上我有一个看起来像这样的视图模型:

public class KorisnikDugovanjaViewModel
    {
        public IEnumerable<Dug> Dugovanja { get; set; }
        public IEnumerable<Korisnik> Korisnici { get; set; }
        public Korisnik Korisnik { get; set; }

        public decimal UkupnoDuznik { get; set; }
        public decimal UkupnoVjerovnik { get; set; }

        public IEnumerable<SumaPoDuzniku> SumePoDuzniku { get; set; }
        public IEnumerable<SumaPoVjerovniku> SumePoVjerovniku { get; set; }
    }

    public class SumaPoDuzniku
    {
        public string Ime { get; set; }
        public decimal Iznos { get; set; }
    }

    public class SumaPoVjerovniku
    {
        public string Ime { get; set; }
        public decimal Iznos { get; set; }
    }

我需要在索引页面的2个场景中将该模型传递给我的视图,当我在索引页面上POST时,我应该在我的索引metod和我的http post索引方法中填充该模型,或者应该我创建一个看起来像这样的方法,并在需要传递模型时调用它?

public KorisnikDugovanjaViewModel VratiModel()
        {
            int userId = int.Parse(Session["User"].ToString());

            KorisnikDugovanjaViewModel model = new KorisnikDugovanjaViewModel
            {
                Dugovanja = dugRepository.Dugovanja
                    .Where(m => (m.Duznik.Id == userId || m.Vjerovnik.Id == userId)),

                Korisnici = korisnikRepository.Korisnici,

                Korisnik = korisnikRepository.Korisnici.FirstOrDefault(m => m.Id == userId),

                UkupnoDuznik = dugRepository.Dugovanja
                    .Where(m => m.DuznikId == userId && !m.Zatvoreno).Sum(m => m.Iznos),

                UkupnoVjerovnik = dugRepository.Dugovanja
                    .Where(m => m.VjerovnikId == userId && !m.Zatvoreno).Sum(m => m.Iznos),

                SumePoDuzniku = dugRepository.Dugovanja
                    .Where(a => a.DuznikId == userId && !a.Zatvoreno)
                    .GroupBy(a => a.Vjerovnik.Ime)
                    .Select(a => new SumaPoDuzniku
                    {
                        Ime = a.Key,
                        Iznos = a.Sum(b => b.Iznos)
                    }),

                SumePoVjerovniku = dugRepository.Dugovanja
                    .Where(a => a.VjerovnikId == userId && !a.Zatvoreno)
                    .GroupBy(a => a.Duznik.Ime)
                    .Select(a => new SumaPoVjerovniku
                    {
                        Ime = a.Key,
                        Iznos = a.Sum(b => b.Iznos)
                    })
            };

            return model;
        }

或者它通常以完全不同的方式完成?我只是想学习如何有效地构建我的代码。 另外我注意到当我使用表单POST时,页面刷新,VratiModel()方法应返回一个填充了新模型的视图,但事实并非如此,模型保持不变,直到我再次刷新页面,那正常吗?我应该以某种方式使用模型状态吗?我很傻。

奖金问题:我如何处理会话?我应该检查用户是否在每个方法的开头登录?可以在构造函数中完成吗?控制器的构造函数如何实际工作?您可能已经注意到我在userId方法的开头使用了我的VratiModel(),而在所有其他方法上,它看起来有点不好。

1 个答案:

答案 0 :(得分:4)

首先,在控制器中使用非动作方法是完全可以的。但是,您应该注意,从技术上讲,任何 public 方法都可以是一个操作。因此,您的非操作方法应该是受保护的还是私有的,具体取决于您是否需要它们可用于派生类。

至于您的视图模型没有更新帖子,很难说无法看到您的操作。但是,一般来说,你会有类似的东西:

public ActionResult Foo()

[HttpPost]
public ActionResult Foo(FooViewModel model)

换句话说,post动作会接受视图模型作为参数。如果这是您的代码的场景,那么返回您的视图模型的方法应该可以选择接受发布的版本。

protected KorisnikDugovanjaViewModel VratiModel(KorisnikDugovanjaViewModel model = null)

然后,如果模型为null,则创建一个新模型。否则,您只需更改发布的版本。

最后,看起来好像您正在使用一些自定义方法进行身份验证/授权。无论如何,这通常是一个坏主意,但它有可能无法真正帮助你处理你的奖金问题,因为我们无法了解所有这些是如何工作的。但是,如果你使用开箱即用的解决方案,比如Identity,事情就很容易了。

为了确保操作受到保护,以便用户需要登录才能访问它,您只需使用[Authorize]修饰您的操作/控制器。如果您在控制器级别执行此操作,则默认情况下将授权所有操作。

[Authorize]
public class MyController : Controller

然后,您无需检查操作中的任何内容。用户将自动为该操作提供服务或重定向到登录页面以进行自我授权。

如果您确实需要某些有关该用户的信息,可以通过User获取该信息。它是控制器上的内置属性。特别是,您可以执行User.Identity.Name之类的操作来获取用户名,或User.Identity.GetUserId()来获取用户的ID。如果您需要数据库中用户表中的更多特定信息,则可以使用用户的ID进行查询。