![](/img/trans.png)
[英]Creating a .Net Standard library referencing ActionFilters, HTTPContext , HTTPException etc
[英]HttpContext in .net standard library
我正在處理幾個項目,其中一個是ASP.NET 4.5
應用程序,另一個是.Net Core API 1.1
項目。 asp.net 應用程序使用HttpContext
類來讀取 cookie 和頁面標題。 現在,我需要將它移動到一個 .net 標准庫,它可以被兩個項目使用。 我在 .net 標准 SDK 中沒有找到 HttpContext。 有什么建議么?
您的方法有一個問題:.NET Standard 是可用的 .NET 最簡單的實現,這意味着只實現了與平台和場景無關的基本功能。
HttpContext
存在於 .NET Framework 和 .NET Core(順便說一下,兩者都實現了 .NET Standard),但特定於 Web,它不存在於 .NET Standard 中。
所以,你有三個選擇:
System.Web.HttpContext
Microsoft.AspNetCore.Http.HttpContext
HttpContext
的邏輯從 .NET Standard 項目中移開但是請注意,這些類差異很大。 .NET Core 版本是為 ASP.NET Core 創建的,它與 ASP.NET 4.5 及更早版本有很大不同。
我不同意這些答案以及關於在 web 項目中只擁有HttpContext
的無意義。 這實際上是緊密耦合的,因為您希望能夠重用代碼,因此 .net 核心或 .net 標准中的類庫應該能夠使用HttpContext
因此,在 .NET Standard 中,您要添加:
Microsoft.AspNetCore.Http.Abstractions
可悲的是,盡管新的 HttpContext HttpContext.Current
有很多不同之處,但缺少會話和請求等。
(是的,我了解了設計模式以及為什么要分離出來並使其更易於測試)
這里有一個小技巧,您也可以使用它來獲取Current
namespace System.Web
{
public static class HttpContext
{
private static Microsoft.AspNetCore.Http.IHttpContextAccessor m_httpContextAccessor;
public static void Configure(Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor)
{
m_httpContextAccessor = httpContextAccessor;
}
public static Microsoft.AspNetCore.Http.HttpContext Current
{
get
{
return m_httpContextAccessor.HttpContext;
}
}
}
}
如果您的目標是 .NETStandard 2.0,您可以使用HttpContext
。
雖然它不包含在.NET Standard庫中,但Microsoft.AspNetCore.Http.Abstractions
包(面向 .NET Standard 2.0)將使您能夠使用HttpContext
。
我需要將這個 [讀取 cookie 和頁眉] 移動到一個 .NET 標准庫,它可以被兩個項目使用......
不要這樣做。
假設您正在對從 cookie 中讀取的數據執行操作 X。 您可以將此操作 X 移到庫中。 ASP.NET 項目的工作是處理請求管道。 閱讀餅干屬於那里。
我同意上面的答案,如果可能的話,您希望保持 netstandard 庫簡單並且沒有網絡請求。 有一個面向 .net 標准的 System.Net.Http nuget 包。 如果您正在創建一個庫並且不想要 asp.net core 的開銷,則可以在為完整框架和 .net core 更新 4.6.x 時使用它。
一種方法是讓調用進程將 Http.Current.Request 作為類型對象的參數傳遞到標准類中的方法中。 然后使用反射訪問屬性。 在您的標准課程中,例如:
public void ProcessRequest(object Request)
{
Type oT = Request.GetType();
string URL = oT.GetProperty("RawUrl").GetValue(Request).ToString();
// do something
}
然后從您的呼叫應用程序:
oRR.ProcessRequest(HttpContext.Current.Request);
我已經從 .Net Framework 測試過這個,而不是來自 .Net Core。 如果 Core 中的上下文庫具有不同的屬性,您可能需要檢查 GetType 返回的類型來決定要訪問哪些屬性名稱。
我知道您想要 HttpContext 但可能對創建任何頻道幾乎沒有幫助。 因此,我給出了一個 ContextChannel 示例。 因為我對類似的 http 上下文感興趣。
我只是創建 ContextChannel 然后我使用 OperationContext 因為如果我沒有創建上下文范圍 Context Channel 總是變得空。
在我的示例中,它的工作方式如下;
ChannelFactory<T> factory = channelFactory;
factory.Endpoint.EndpointBehaviors.Add(new ClientMessagePropertyBehavior());
var proxy = (IClientChannel)factory.CreateChannel();
using (var contextScope = new OperationContextScope((IContextChannel)proxy))
{
Stopwatch sw = Stopwatch.StartNew();
HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers["Authorization"] = accessToken;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
TResult result = codeBlock((T)proxy);
sw.Stop();
_tools.logInfo(string.Format(@"* Service client performance : {0} = {1} ms", codeBlock.Method.ToString(), sw.ElapsedMilliseconds));
success = true;
return result;
}
您可以在調用舊類之前創建 HttpContext.Current :
使用 System.Web; 使用 System.Web.SessionState;
System.Web.HttpContext.Current = new System.Web.HttpContext(new System.Web.HttpRequest("", "http://localhost", ""), new System.Web.HttpResponse(new System.IO.StringWriter ())); System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext(System.Web.HttpContext.Current, new HttpSessionStateContainer("", new SessionStateItemCollection(), new HttpStaticObjectsCollection(), 20000, true, HttpCookieMode.UseCookies, SessionStateMode.InProc, false));
HttpContext.Session.SetString("your_session_var", "1");
foreach (string item in HttpContext.Session.Keys)
{
System.Web.HttpContext.Current.Session[item] = HttpContext.Session.GetString(item);
}
**調用舊的類庫方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.