C# 从url返回HTML的HtmlHelper(基本上是代理)
我正在尝试创建一个基于Html.RenderAction工作方式的HtmlHelper。它与RenderAction的不同之处在于,除了“ActionName”和“ControllerName”之外,它还将获取一个字符串,该字符串将依次对应于Web.Config中的一个值。配置中的此值是URL的值 这样做的原因是,尽管我的控制器/操作在它自己的本机项目中工作得很好,但我需要从它的兄弟项目中获得此控制器/操作的结果。我打算通过使用助手和当前保存在每个兄弟项目的Web.Config中的详细信息构建所需的URL来实现这一点 我已经有了以下代码:C# 从url返回HTML的HtmlHelper(基本上是代理),c#,asp.net-mvc,razor,html-helper,C#,Asp.net Mvc,Razor,Html Helper,我正在尝试创建一个基于Html.RenderAction工作方式的HtmlHelper。它与RenderAction的不同之处在于,除了“ActionName”和“ControllerName”之外,它还将获取一个字符串,该字符串将依次对应于Web.Config中的一个值。配置中的此值是URL的值 这样做的原因是,尽管我的控制器/操作在它自己的本机项目中工作得很好,但我需要从它的兄弟项目中获得此控制器/操作的结果。我打算通过使用助手和当前保存在每个兄弟项目的Web.Config中的详细信息构建所
public static void RenderActionToSpecifiedAssembly(this HtmlHelper helper, string actionName, string controllerName, string parentAssembly)
{
var uriFromWebConfig = new Uri(ConfigurationManager.AppSettings[parentAssembly]);
//uriFromWebConfig == "http://ProjectNumberOne.com/"
var parentUri = new Uri(uriFromWebConfig);
var path = controllerName + "/" + actionName;
var redirect = new Uri(parentUri, path).AbsoluteUri;
//var redirect == "http://ProjectNumberOne.com/MyController/MyAction"
//******************
}
我现在正在努力解决的是在**********家放些什么。我想让这个助手做的是返回的结果
- 如果我在地址栏中键入此URL,它将返回预期的html页面李>
- 如果在父项目中使用Html.RenderAction(“MyAction”、“MyController”),它将返回预期的Html页面
有什么想法吗?你文章中的一些细节让你很难确定你是想通过使用反射还是使用http来实现你的目标(或者你不在乎,只要你能得到你想要的结果) 我不建议您尝试利用反射来实现这一点。(这有很多原因,但重要的是使用http将更容易、更直接) 根据您发布的内容,我将使用的方法是创建一个
HtmlHelper
,它呈现一个IFRAME
标记,其中所需的URL为src
类似这样(顺便说一句,这里有很多防御编码的机会):
我假设您的应用程序的业务需要位于不同的站点/项目中。但是,如果这不是强制性的,那么您可能会考虑是否有可能以不同的方式组织相关内容(例如,具有多个区域而不是多个站点的单一站点),这将使您更容易地共享它们之间的内容/行为。p> 我发现,尽管David提供的IFRAME方法按要求工作,但使用IFRAME仍然让我感到不安。这篇文章让我意识到它们并不那么好: 我发现以下实施达到了目的,并给了我所需的结果:
public static IHtmlString RenderActionToSpecifiedAssembly(this HtmlHelper helper, string actionName, string controllerName, string parentAssembly)
{
var parentWebConfigarentValue = new Uri(ConfigurationManager.AppSettings[parentAssembly]);
var path = controllerName + "/" + actionName;
var redirect = new Uri(parentWebConfigarentValue, path).AbsoluteUri;
var request = (HttpWebRequest)WebRequest.Create(redirect);
var result = (HttpWebResponse)request.GetResponse();
String responseString;
using (Stream stream = result.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
return new HtmlString(responseString);
}
使用这种方法,我可以向父控制器/操作发出请求,将其写入字符串,然后将HTML返回到要呈现的页面。工作的魅力!:) 您的解决方案可以更好地解释您想要什么,但非常缺乏灵活性。如果需要向请求传递其他路由值,该怎么办?最好通过提供重载来模拟UrlHelper类,您可以使用重载来构建任何您想要的URL
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
public static class HtmlHelperExtensions
{
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(
helper, actionName, null, null, null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, object routeValues,
string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
null, new RouteValueDictionary(routeValues), null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, null, null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, RouteValueDictionary routeValues,
string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
null, routeValues, null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
object routeValues, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, new RouteValueDictionary(routeValues),
null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
RouteValueDictionary routeValues, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, routeValues, parentAssembly, null);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
object routeValues, string protocol, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, routeValues, protocol, parentAssembly, null);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
RouteValueDictionary routeValues, string parentAssembly, string port)
{
var hostName = ConfigurationManager.AppSettings[parentAssembly];
var url = GenerateContentUrl(helper, actionName,
controllerName, routeValues, null, hostName, port);
return RenderContents(url);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
object routeValues, string protocol, string parentAssembly, string port)
{
var hostName = ConfigurationManager.AppSettings[parentAssembly];
var url = GenerateContentUrl(helper, actionName,
controllerName, new RouteValueDictionary(routeValues),
protocol, hostName, port);
return RenderContents(url);
}
private static string GenerateContentUrl(this HtmlHelper helper,
string actionName, string controllerName, RouteValueDictionary routeValues,
string protocol, string hostName, string port)
{
var currentUri = helper.ViewContext.RequestContext.HttpContext.Request.Url;
// Ensure we have an absolute path
if (string.IsNullOrEmpty(protocol) && string.IsNullOrEmpty(hostName))
{
// Match the scheme of the current request so we don't get a
// security warning in the browser.
protocol = currentUri.Scheme;
}
// Allow caller to override the port so it doesn't have
// to be the same as the current request.
string currentUrl = currentUri.Scheme + Uri.SchemeDelimiter
+ currentUri.DnsSafeHost;
if (!string.IsNullOrEmpty(port))
{
currentUrl += ":" + port;
}
currentUrl += "/";
var homePageUri = new Uri(new Uri(currentUrl, UriKind.Absolute), "/");
// Create a TextWriter with null stream as a backing stream
// which doesn't consume resources
using (var nullWriter = new StreamWriter(Stream.Null))
{
// Create a fake context at the home page to ensure that ambient values
// from the request are excluded from the generated URL.
// See: https://aspnetwebstack.codeplex.com/workitem/1346
var httpContext = CreateHttpContext(homePageUri, nullWriter);
var requestContext = new RequestContext(httpContext, new RouteData());
return UrlHelper.GenerateUrl(null, actionName, controllerName,
protocol, hostName, null, routeValues, helper.RouteCollection,
requestContext, true);
}
}
private static HttpContextBase CreateHttpContext(Uri uri, TextWriter writer)
{
if (uri == null)
throw new ArgumentNullException("uri");
if (writer == null)
throw new ArgumentNullException("writer");
var request = new HttpRequest(string.Empty, uri.ToString(), uri.Query);
var response = new HttpResponse(writer);
var httpContext = new HttpContext(request, response);
return new HttpContextWrapper(httpContext);
}
private static IHtmlString RenderContents(string url)
{
var request = (HttpWebRequest)WebRequest.Create(url);
var result = (HttpWebResponse)request.GetResponse();
String responseString;
using (Stream stream = result.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
return new HtmlString(responseString);
}
}
您可能还希望解析配置值之外的端口,以便在其中配置http和https URL,并将它们与主机名紧密绑定在一起,这样可以消除一些重载。在这种情况下,您可能应该使用当前请求的协议来确定要检索并删除作为传入值的协议的配置值(HTTP或HTTPS)。您的问题是
ConfigurationManager.AppSettings[parentAssembly]
返回空值而不是web.config上的值?这个值是如何分配的?我认为应该像parentASsembly=Assembly.GetEntryAssembly()
那样设置此变量。同样,考虑用反射<代码>配置管理器来标记这类问题。AppStase[PaleStuts] < /Cord>按预期返回。我传递字符串“ProductOne”作为helper方法的第三个参数。从那里,该方法本身在Web.Config中查看针对名为“ProductOne”的项保留的内容。(在本例中,它是一个URL)。我的问题是,当我在Product2或Product3中时,我希望它从http获得结果//ProjectNumberOne.com/MyController/MyAction,而不是http//ProjectNumberTwo.com/MyController/MyAction或http//ProjectNumberThree.com/MyController/myaction很难确切地说出您想要的是什么,但在我看来,您试图从每个程序集的不同配置中获取配置值。你们可能想看一看。我已经把标题改为我认为反映你们问题的内容——请随意改进。您可能希望从问题中删除与实际问题不直接相关的大部分代码(即,可以安全地删除所有与配置相关的代码/文本)。我同意,反射不是我试图完成此问题结果的方式。看起来你已经明白我的问题了:)我早上上班时得试试IFrame。是的,不幸的是,这4个独立的产品已经被设计、编码和发布;我刚刚开始我目前的工作,有很多重构的工作。对于这个特殊问题的理想解决方案应该是SPA方法,但时间和成本对我不利。我会告诉你我的进展。感谢您的评论,很明显,许多功能都可以重构为封装自己关注点的单个方法,但为了在互联网上使用,更容易在一个方法中完成。旁注:运行非琐碎的代码(如查询数据库或远程服务器的代理页面)通常不建议将其作为视图逻辑的一部分。它还(在ASP.Net MVC v6问世之前)阻止您将此代码设置为异步(因为在ASP.Net MVC 5及以下版本中,视图/子操作不支持异步处理)。旁注2:显然,只有在外部服务器呈现时,才会生成有效页面
public static IHtmlString RenderActionToSpecifiedAssembly(this HtmlHelper helper, string actionName, string controllerName, string parentAssembly)
{
var parentWebConfigarentValue = new Uri(ConfigurationManager.AppSettings[parentAssembly]);
var path = controllerName + "/" + actionName;
var redirect = new Uri(parentWebConfigarentValue, path).AbsoluteUri;
var request = (HttpWebRequest)WebRequest.Create(redirect);
var result = (HttpWebResponse)request.GetResponse();
String responseString;
using (Stream stream = result.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
return new HtmlString(responseString);
}
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
public static class HtmlHelperExtensions
{
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(
helper, actionName, null, null, null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, object routeValues,
string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
null, new RouteValueDictionary(routeValues), null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, null, null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, RouteValueDictionary routeValues,
string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
null, routeValues, null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
object routeValues, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, new RouteValueDictionary(routeValues),
null, parentAssembly);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
RouteValueDictionary routeValues, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, routeValues, parentAssembly, null);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
object routeValues, string protocol, string parentAssembly)
{
return RenderActionToSpecifiedAssembly(helper, actionName,
controllerName, routeValues, protocol, parentAssembly, null);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
RouteValueDictionary routeValues, string parentAssembly, string port)
{
var hostName = ConfigurationManager.AppSettings[parentAssembly];
var url = GenerateContentUrl(helper, actionName,
controllerName, routeValues, null, hostName, port);
return RenderContents(url);
}
public static IHtmlString RenderActionToSpecifiedAssembly(
this HtmlHelper helper, string actionName, string controllerName,
object routeValues, string protocol, string parentAssembly, string port)
{
var hostName = ConfigurationManager.AppSettings[parentAssembly];
var url = GenerateContentUrl(helper, actionName,
controllerName, new RouteValueDictionary(routeValues),
protocol, hostName, port);
return RenderContents(url);
}
private static string GenerateContentUrl(this HtmlHelper helper,
string actionName, string controllerName, RouteValueDictionary routeValues,
string protocol, string hostName, string port)
{
var currentUri = helper.ViewContext.RequestContext.HttpContext.Request.Url;
// Ensure we have an absolute path
if (string.IsNullOrEmpty(protocol) && string.IsNullOrEmpty(hostName))
{
// Match the scheme of the current request so we don't get a
// security warning in the browser.
protocol = currentUri.Scheme;
}
// Allow caller to override the port so it doesn't have
// to be the same as the current request.
string currentUrl = currentUri.Scheme + Uri.SchemeDelimiter
+ currentUri.DnsSafeHost;
if (!string.IsNullOrEmpty(port))
{
currentUrl += ":" + port;
}
currentUrl += "/";
var homePageUri = new Uri(new Uri(currentUrl, UriKind.Absolute), "/");
// Create a TextWriter with null stream as a backing stream
// which doesn't consume resources
using (var nullWriter = new StreamWriter(Stream.Null))
{
// Create a fake context at the home page to ensure that ambient values
// from the request are excluded from the generated URL.
// See: https://aspnetwebstack.codeplex.com/workitem/1346
var httpContext = CreateHttpContext(homePageUri, nullWriter);
var requestContext = new RequestContext(httpContext, new RouteData());
return UrlHelper.GenerateUrl(null, actionName, controllerName,
protocol, hostName, null, routeValues, helper.RouteCollection,
requestContext, true);
}
}
private static HttpContextBase CreateHttpContext(Uri uri, TextWriter writer)
{
if (uri == null)
throw new ArgumentNullException("uri");
if (writer == null)
throw new ArgumentNullException("writer");
var request = new HttpRequest(string.Empty, uri.ToString(), uri.Query);
var response = new HttpResponse(writer);
var httpContext = new HttpContext(request, response);
return new HttpContextWrapper(httpContext);
}
private static IHtmlString RenderContents(string url)
{
var request = (HttpWebRequest)WebRequest.Create(url);
var result = (HttpWebResponse)request.GetResponse();
String responseString;
using (Stream stream = result.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
return new HtmlString(responseString);
}
}