Asp.Net:从一个类中返回一个读者

Mel*_*elt 3 asp.net ado.net encapsulation data-access-layer class

我只是想知道从课堂上找回读者的正确方法?

我的代码可以使用,但我不确定这是否正确.

也.我无法关闭我的类方法中的连接,仍然可以从我的ascx页面访问它,是

那好吗?

//在我的班级中,我有以下方法来返回记录/阅读器 - 在这种情况下它是一条记录.

public SqlDataReader GetPost()
    {
        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand("con_spPost", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@blogid", blogid);
        try
        {
            conn.Open();
            return cmd.ExecuteReader();
        }
        finally
        {
          //  conn.Close();
        }
    }
Run Code Online (Sandbox Code Playgroud)

//然后我在ascx页面中调用GetPost方法,如下所示:

protected void Page_Load(object sender, EventArgs e)
{

    //instantiate our class
    MyClass DB = new MyClass();

    //pass in the id of the post we want to view
    DB.PostID = Int32.Parse(Request.QueryString["p"]);

    ///call our GetPost method
    SqlDataReader reader = DB.GetPost();

   //output the result
    reader.Read();
    this.viewpost.InnerHtml = "<span id='post1_CreatedDate'>" + reader["CreatedDate"].ToString() + "</span><br>";
    this.viewpost.InnerHtml += "<span class='blogheads'>" + reader["BlogTitle"].ToString() + "</span><p><p>";
    this.viewpost.InnerHtml += reader["BlogText"].ToString();
    reader.Close();
}
Run Code Online (Sandbox Code Playgroud)

感谢您对我的代码或提示的任何评论.

熔化

Jef*_*nal 6

一般来说,从一个方法返回一个读者是好的,但读者的消费者需要控制将在读者的一生中使用的所有一次性对象.

为此,您需要IDbConnection传入GetPost方法,然后确保您的调用者同时处理连接和读取器.该using关键字是做到这一点的最方便的方法:

protected void Page_Load(object sender, EventArgs e) {

    // Create the DB, get the id, etc.    

    using (IDbConnection connection = new SqlConnection(connectionString))
    using (IDataReader reader = DB.GetPost(connection)) {
        reader.Read();
        this.viewpost.InnerHtml = reader["BlogText"].ToString();
        // finishing doing stuff with the reader  
    }
}
Run Code Online (Sandbox Code Playgroud)

正如其他人所指出的那样,这开始使用过多的数据访问基础架构使应用程序的表示层变得混乱 - 所以这里不适合.在您发现自己遇到性能问题或需要显示不合理数据量之前,您不应该在表示层中处理数据读取器.只需DB.GetPost返回一个字符串,并将所有数据访问代码封装在那里.


SLa*_*aks 5

要确保连接已关闭,ExecuteReader请使用以下内容替换呼叫:

return cmd.ExecuteReader(CommandBehavior.CloseConnection);
Run Code Online (Sandbox Code Playgroud)

您还应该删除te try/ finallyblock.

此外,在您的Page_Load处理程序中,您应该使用一个using语句,如下所示:

using (SqlDataReader reader = DB.GetPost()) {

    //output the result
    reader.Read();
    this.viewpost.InnerHtml = "<span id='post1_CreatedDate'>" + reader["CreatedDate"].ToString() + "</span><br>"
        + "<span class='blogheads'>" + reader["BlogTitle"].ToString() + "</span><p><p>"
        +  reader["BlogText"].ToString();
}
Run Code Online (Sandbox Code Playgroud)

此外,您应该检查SQL查询实际返回了什么,如下所示:

if (!reader.Read()) {
    Something's wrong
}
Run Code Online (Sandbox Code Playgroud)

最后,也是最重要的,你应该通过调用来转义HTML来防止XSS漏洞Server.HtmlEncode.

例如:

    this.viewpost.InnerHtml = "<span id='post1_CreatedDate'>" + reader["CreatedDate"].ToString() + "</span><br>"
        + "<span class='blogheads'>" + Server.HtmlEncode(reader["BlogTitle"].ToString()) + "</span><p><p>"
        + Server.HtmlEncode(reader["BlogText"].ToString());
Run Code Online (Sandbox Code Playgroud)