您的位置:首页 > 移动开发

自定义WebViewPage,实现Url.Action生成绝对地址

2015-10-29 16:53 323 查看
前言

运营部门一直对公司官网SEO有意见,认为做得不好(说得好像运营做不好都是seo似的)。为此两部门老大还闹到CEO那去了。

也因为这事,工作计划终于排上日程。沟通一番后得知有如下几点需求:

1.所有链接都得是绝对地址。比如之前是/about.html,现在得变成http://xxx.com/about.html(你妹啊,这样我本地怎么测试)

2.所有目录最后都加/,没有的定久重定向到加/的。比如之前/xxx ,现在得变成http://xxx.com/xxx/

3.图片必须加alt ,width height 属性

分析编码

前些天图片问题已经改完了,现在重点是链接。因为项目链接大多走的Url.Action,所以自然的想到得从这入手。

其实微软已经为我们提供了这个实现,即 @Url.Action("actionName","controllerName","routeValues","protocol","hostName")

全解决方案搜索Url.Action,一千多处。想到前面优化img标签加alt,才五百多处就花了一天半时间,这肯定是不能接受的。

mvc 不是开源了吗,把源码down下来看看,https://git01.codeplex.com/aspnetwebstack

分析源码定位到两个核心的类 UrlHelper WebViewPage

using System;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.WebPages;
using System.Collections.Generic;
using MSP.Common.Tools;

namespace SF.MVC.Core
{
public class CustomUrlHelper : UrlHelper
{
/// <summary>
/// 是否需要加端口号
/// </summary>
private static bool IsNeedProtocol = false;

public CustomUrlHelper(RequestContext requestContext)
: base(requestContext, RouteTable.Routes)
{
ConfigManager config = new ConfigManager();
config.LoadConfig("common");

string configValue = config.GetConfig("NeedProtocol") == null ? "false" : config.GetConfig("NeedProtocol").Value;

bool.TryParse(configValue, out IsNeedProtocol);

}

public new string Action(string actionName, string controllerName)
{
var hostName = RequestContext.HttpContext.Request.Url.Host;
return GenerateUrl(null, actionName, controllerName, null, hostName, null, (RouteValueDictionary)null, RouteCollection, RequestContext, true);
}

public new string Action(string actionName, string controllerName, object routeValues)
{
var hostName = RequestContext.HttpContext.Request.Url.Host;
return GenerateUrl(null, actionName, controllerName, null, hostName, null, new RouteValueDictionary(routeValues), RouteCollection, RequestContext, true);
}

public new string RouteUrl(string routeName)
{
var hostName = RequestContext.HttpContext.Request.Url.Host;
return GenerateUrl(routeName, null, null, null, hostName, null, (RouteValueDictionary)null, RouteCollection, RequestContext, false);

}

public new static string GenerateUrl(string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues)
{
string url = GenerateUrl(routeName, actionName, controllerName, routeValues, routeCollection, requestContext, includeImplicitMvcValues);

if (url != null)
{
if (!IsContain(url))
url += "/";

if (!String.IsNullOrEmpty(fragment))
{
url = url + "#" + fragment;
}

if (!String.IsNullOrEmpty(protocol) || !String.IsNullOrEmpty(hostName))
{
Uri requestUrl = requestContext.HttpContext.Request.Url;
protocol = (!String.IsNullOrEmpty(protocol)) ? protocol : Uri.UriSchemeHttp;
hostName = (!String.IsNullOrEmpty(hostName)) ? hostName : requestUrl.Host;

string port = String.Empty;
string requestProtocol = requestUrl.Scheme;

if (IsNeedProtocol && String.Equals(protocol, requestProtocol, StringComparison.OrdinalIgnoreCase))
{
port = requestUrl.IsDefaultPort ? String.Empty : (":" + Convert.ToString(requestUrl.Port, CultureInfo.InvariantCulture));
}

url = protocol + Uri.SchemeDelimiter + hostName + port + url;
}
}

return url;
}

/// <summary>
/// 判断字符串中是否包含某部分
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static bool IsContain(string input)
{
if (string.IsNullOrWhiteSpace(input)) return false;

if (input == "/")
{
return true;
}
else if(input.Contains("articledetial"))
{
return true;
}
else if (input.Contains("special"))
{
return true;
}
else if(input.EndsWith(".html", StringComparison.CurrentCultureIgnoreCase))
{
return true;
}

return false;
}

}
}


修改后CustomUrlHelper
代码中构造函数读取配置您需要改写成自己的实现逻辑。

参考:

Changing Base Type Of A Razor View

Create Your Own Custom ViewWebPage for ASP.NET MVC

MVC中自定义ViewPage和WebViewPage
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: