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

oje*_*jek 0 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");
}
Run Code Online (Sandbox Code Playgroud)

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

<img src="/MyAccount/GetImage/?user=@User.Identity.Name" 
     alt="@User.Identity.Name" />
Run Code Online (Sandbox Code Playgroud)

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

Dar*_*rov 7

为什么?

因为您已将url硬编码到控制器操作而不是使用url帮助器:

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

您永远不应该在ASP.NET MVC应用程序中硬编码URL,但始终使用url帮助程序.

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

因此,首先要删除此查询字符串参数:

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

然后在您的控制器操作中,您始终可以使用该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);
}
Run Code Online (Sandbox Code Playgroud)

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