我一直在做一些搜索,但找不到我想要的东西。
我正在开发一个Umbraco项目,需要在父页面内呈现特定页面的内容。
我试过
@Html.Action("MyAction", "MyController")
但是这导致我的页面的已分配内容项为空(因为我已经去了动作而不是去umbraco网址)这并不是一个很大的惊喜。
是否有像Html
这样的Action
方法接受网址而不是操作名称和控制器名称?
我喜欢这样的事情
@Html.LoadUrl("~/my-controller-section/my-action-page")
我自己可以写一个扩展来做这件事,但我真的希望MVC内置一些内容来做到这一点。我不想重新发明轮子。
我正在使用ASP.Net MVC 4。
答案 0 :(得分:0)
好的,所以似乎没有办法在MVC中这样做,所以我不情愿地推出自己的。如果内置的方法可以解决这个问题,我会把它换掉。
我已经在我的问题中实现了我提出的LoadUrl方法,就像这样消耗:
@Html.LoadUrl("http://foo/bar")
实现看起来像这样(对不起,它有点长,但我想要包含一个完整的工作示例,以便您可以复制并粘贴它。)
您会注意到我在请求中设置了身份验证cookie,否则它只会返回登录页面而不是请求的页面。我已经专门为表单身份验证实现了这个。如果您的站点不使用身份验证,则不需要此部分。
public static class MvcExtensions
{
/// <summary>
/// Invokes a request to the specified url and returns the result as an HTML string.
/// </summary>
/// <param name="thisHtml">The HTML helper instance that this method extends.</param>
/// <param name="url">The url to invoke the request on.</param>
/// <returns>The url contents as an HTML string.</returns>
public static MvcHtmlString LoadUrl(this HtmlHelper thisHtml, string url)
{
//get the url as an absolute url
UrlHelper helper = GetUrlHelper();
url = helper.Absolute(url);
var request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
//set the auth cookie so we don't just get the login page
request.SetAuthenticationCookie();
//get the response
string responseString = request.GetResponseString();
//return it as an html string
return new MvcHtmlString(responseString);
}
private static UrlHelper GetUrlHelper()
{
return new UrlHelper(HttpContext.Current.Request.RequestContext);
}
/// <summary>
/// Gets an absolute version of the specified url relative to the current requests url root.
/// </summary>
/// <param name="thisHelper">The Url helper instance that this method extends.</param>
/// <param name="url">The url to get an absolute version of.</param>
/// <returns>An absolute version of the specified url relative to the current requests url root.</returns>
public static string Absolute(this UrlHelper thisHelper, string url)
{
//only make the url absolute if it isn't already
if (!url.Contains("://"))
{
return string.Format("http://{0}{1}", thisHelper.RequestContext.HttpContext.Request.Url.Authority, thisHelper.Content(url));
}
else
{
return url;
}
}
/// <summary>
/// Sets the authentication cookie of the specified request.
/// </summary>
/// <param name="request">The request to set the cookie for.</param>
/// <param name="authenticationCookie">(Optional) The cookie to add to the request, if not specified defaults
/// to the cookie of the user currently logged into the site.</param>
public static void SetAuthenticationCookie(this HttpWebRequest request, Cookie authenticationCookie = null)
{
if (authenticationCookie == null)
{
//add the current authentication cookie to the request
var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
authenticationCookie = new System.Net.Cookie
(
FormsAuthentication.FormsCookieName,
cookie.Value,
cookie.Path,
FormsAuthentication.CookieDomain
);
}
request.CookieContainer = new System.Net.CookieContainer();
request.CookieContainer.Add(authenticationCookie);
}
/// <summary>
/// Gets the response string from the specified request.
/// </summary>
/// <param name="request">The request to get the response string from.</param>
/// <returns>The response string from the specified request.</returns>
public static string GetResponseString(this System.Net.WebRequest request)
{
System.Net.WebResponse response = null;
try
{
response = request.GetResponse();
}
catch (System.Net.WebException webException)
{
response = webException.Response;
throw;
}
return GetResponseString(response);
}
/// <summary>
/// Gets the response string from the specified response.
/// </summary>
/// <param name="response">The response to get the response string from.</param>
/// <returns>The response string from the specified response.</returns>
public static string GetResponseString(this System.Net.WebResponse response)
{
using (var responseTextStream = new System.IO.StreamReader(response.GetResponseStream()))
{
return responseTextStream.ReadToEnd();
}
}
}