MVC分离关注点

时间:2012-01-29 00:20:52

标签: asp.net-mvc-3

所以我开始创建我的MVC 3网络应用程序时,我突然意识到我可能在我的控制器中放置了太多的逻辑,它需要在模型中。这个问题是,在这个特定的实例中,我正在处理一个文件。

SQL数据库表存储文件的路径,文件本身保存在目录中。所以在数据库中,文件路径存储为nvarchar,在模型中,文件是一个字符串,一切都与该点一致。当上传文件的时候出现问题,那时我正在处理System.IO.File。

所以问题是,如果在后端它实际上是一个字符串,你如何在模型中为文件提供System.IO.File逻辑呢?

我已经完成了Controller的功能版本,并且已经有了一些逻辑,当我意识到我正在对抗系统时,它还要添加更多。我的意思是,为了进行服务器端验证,逻辑需要在模型中,以便输入验证能够根据适当的MVC规则运行和工作,显然可选地结合客户端验证。

目前...

这是我的观点:

@model ProDevPortMVC3.Profile

@{
    ViewBag.Title = "Profile Photo Upload";
}

<h2>Photo Upload</h2>

<img alt="Profile Image" src="@Html.DisplayFor(model => model.ProfilePhotoPath)" />

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm("UploadPhoto", "Profile", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)
    <br />
    <input  type="file" name="File1" />
    @Html.ValidationMessageFor(model => model.ProfilePhotoPath)
    <input type="submit" value="Upload" />
}

这是我的控制器(只是相关的操作方法):

    [HttpPost]
    public ActionResult UploadPhoto(int id, FormCollection form)
    {
        Profile profile = db.Profiles.Find(id);

        var file = Request.Files[0];

        if (file != null && file.ContentLength > 0)
        {
            try
            {
                string newFile = Path.GetFileName(file.FileName);
                file.SaveAs(Server.MapPath("/Content/users/" + User.Identity.Name + "/" + newFile));
                profile.ProfilePhotoPath = "/Content/users/" + User.Identity.Name + "/" + newFile;
                UpdateModel(profile);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
        return View();
    }

这是我的模型(只是与文件相关的部分):

    public string ProfilePhotoPath { get; set; }

所以我想,在这些特殊情况下,你们的解决方案是什么?

2 个答案:

答案 0 :(得分:1)

描述

假设我理解你的问题。我已经读了几遍你的问题了。 ;)如果我不明白,请评论我的答案,以获得更好的答案(我会更新)

我认为您想要的是......如何针对您的特定情况进行模型验证。

您可以使用ModelState.AddModelError("Key", "Message)方法添加模型验证错误。

  

ModelState.AddModelError 将模型错误添加到模型状态字典的错误集合中。

示例

ModelState.AddModelError("ProfilePhotoName", "YourMessage");

这会影响ModelState.IsValid

所以你可以做任何你想做的事情(你的逻辑)并且可以使你的模型无效。

更多信息

答案 1 :(得分:0)

这个问题有很多答案。由于意见不一,我会知道风险正在进行中。根据我对MVC3的个人经验,我喜欢使用更平坦,更简单的模型。如果有一些验证可以在不需要外部依赖关系的几行代码中轻松完成,那么我将在模型中进行验证。我觉得你的System.IO逻辑本身并不是验证。在我看来,模型中可能存在的验证是文件名是否为零长度。保存的逻辑可以放在控制器中。更好的是,您可以使用Inversion of Controller模式注入该逻辑,特别是Dependency Injection解决方案。