返回FilePath的Action方法有时无效。为什么?

时间:2013-02-02 18:15:31

标签: c# asp.net asp.net-mvc asp.net-mvc-3

我有这个:

[AllowAnonymous]
public FilePathResult GetImage(string user)
{
    var path = AppDomain.CurrentDomain.BaseDirectory + "files\\uploads\\users\\" + user + "\\avatar\\";
    var ext = this.GetImageExtension(path, user);
    return ext != null ? File(path + user + "." + ext, "image/" + ext, user + "." + ext) : File(AppDomain.CurrentDomain.BaseDirectory + "files\\commonFiles\\users\\avatar\\noavatar.png", "image/png", "noavatar.png");
}

在我的观点中,我有这个:

<img src="/MyAccount/GetImage/?user=@User.Identity.Name" 
     alt="@User.Identity.Name" />

现在,每当我在我的Web开发人员服务器中使用它时,它都可以正常工作。但是,当我在我的服务器上发布我的网站时,它甚至都没有尝试执行该操作。为什么呢?

1 个答案:

答案 0 :(得分:7)

  

为什么?

因为你已经将url硬编码到你的控制器动作而不是使用url helper:

<img src="@Url.Action("GetImage", "MyAccount", new { user = User.Identity.Name })" alt="@User.Identity.Name" />

您永远不应该在ASP.NET MVC应用程序中对URL进行硬编码,但始终使用url helpers。

同样将当前登录的用户作为查询字符串参数传递看起来像一个可怕的安全问题。没有什么可以阻止用户传递他喜欢的任何用户名并咨询该用户的图像。您应该在控制器操作中读取当前经过身份验证的用户。

首先,摆脱这个查询字符串参数:

<img src="@Url.Action("GetImage", "MyAccount")" alt="@User.Identity.Name" />

然后在您的控制器操作中,您始终可以使用User.Identity.Name属性检索当前登录的用户:

[Authorize]
public FilePathResult GetImage()
{
    string user = User.Identity.Name;
    var path = Server.MapPath(
        string.Format("~/files/uploads/users/{0}/avatar/", user)
    );
    var ext = this.GetImageExtension(path, user);
    if (string.IsNullOrEmpty(ext))
    {
        return File(
            Server.MapPath("~/files/commonFiles/users/avatar/noavatar.png"), 
            "image/png", 
            "noavatar.png"
        );
    }
    var file = Path.ChangeExtension(Path.Combine(path, user), ext);
    return File(file, "image/" + ext, user + "." + ext);
}

我还使用[Authorize]属性修饰了此控制器操作,以使其仅对经过身份验证的用户可访问。如果不是这种情况,您仍然可以保留[AllowAnonymous]属性,但在尝试访问其用户名之前请检查User.Identity.IsAuthenticated