如何在Controller或View的上下文之外获取当前HttpRequestBase的实例

时间:2012-01-27 06:54:50

标签: asp.net-mvc

我在做什么:

我正在创建一个电子邮件邮件引擎,它接受html模板,用数据替换令牌,然后将邮件发送到SMTP服务器。最终,我们需要一个CMS UI,以允许他们添加/删除文件模板或通过CMS UI更新其中的内容。无论如何,我将.htm文件放在我的MVC Web项目中的电子邮件模板中,需要读取它们的内容并获取HTML的字符串。如果我将所有这些代码从我的MVC项目中移动到像实用程序C#项目层一样,那么问题是我必须担心维护物理路径(“C:... \ theMVCWebSiteFolder ... \ Email \ Templates \ SomeTemplate。 htm“)那对我来说必须硬编码我认为如果你要将网站移动到不同的服务器,不同的硬盘分区等,请跟踪。所以我希望能够处理这些文件使用当前应用程序的上下文,除非有办法对我的MVC应用程序执行此操作,并且不必担心每次移动文件夹时都必须更改物理根目录的位置。

我在实用程序类中创建了以下实用程序方法,该实用程序类位于我的ASP.NET MVC Web项目中某个文件夹中的文件夹中(任何视图文件夹之外的文件夹:

public static string GetFileData(string filePath)
{
    if (!File.Exists(HttpContext.Current.Request.PhysicalApplicationPath + filePath))
        throw new FileNotFoundException(String.Format("the file {0} was not found", filePath));

    string text;
    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);

    using(StreamReader read = new StreamReader(fileStream))
        text = read.ReadToEnd();

    return text;
}

我试图弄清楚为什么上下文在这里变为空。我最初尝试过HttpContext.Current但是当前是null,因此它无法在我的MVC Web项目中的Utility.cs方法中找到当前上下文。

更新:

好的,所以共识是使用HttpRequestBase对象而不是HttpContext.Current对象。我仍然觉得HttpContext.Current为null很奇怪。但继续前进,如果我的Utility.cs在控制器或视图的任何上下文之外,那么我是如何得到当前请求的实例(HttpRequestBase)来处理并发送实现HttpRequestBase的实例(我不知道)如果我想在控制器或视图之外的“MVC方式”中使用此实用程序方法,那会是什么对象?

3 个答案:

答案 0 :(得分:2)

不知道为什么这会返回null但是因为将业务层与ASP.NET细节绑定是一个坏主意我建议您对方法进行以下更改:

public static string GetFileData(string filePath)
{
    if (!File.Exists(filePath))
        throw new FileNotFoundException(String.Format("the file {0} was not found", filePath));

    return File.ReadAllText(filePath);
}

然后当您需要从Web应用程序中使用它时:

public ActionResult Foo()
{
    var result = MyClass.GetFileData(Server.MapPath("~/foo/bar.txt"));
    ...
}

当你需要在WinForms应用程序中使用它时:

protected void Button1_Click(object sender, EventArgs e)
{
    var filePath = Path.Combine(Environment.CurrentDirectory, "bar.txt");
    var result = MyClass.GetFileData(filePath);
    ...
}

答案 1 :(得分:2)

在实用程序类中,我将删除对任何与Web相关的东西的依赖。

对于相对于应用程序根目录的路径,我将使用:

Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, fileName)

它将为您提供您可能想要的内容(相对于Web应用程序中的Web根目录的路径;相对于WinForms应用程序中包含可执行文件的路径,...)

答案 2 :(得分:1)

如果想以asp.net mvc方式重写该方法,可以用这种方式重写它并删除与HttpContext类的耦合

public static string GetFileData(HttpRequestBase request, string filePath)
{
    if (!File.Exists(request.PhysicalApplicationPath + filePath))
        throw new FileNotFoundException(String.Format("the file {0} was not found", filePath));

    string text;
    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);

    using(StreamReader read = new StreamReader(fileStream))
        text = read.ReadToEnd();

    return text;
}

通常在MVC中HttpContextHttpRequestHttpResponse被抽象为HttpContextBaseHttpRequestBaseHttpResponseBase