Я использую помощника в своих контроллерах и в своих представлениях, которые я нашел где-то в Интернете. Помощник вызывается так в моем контроллере "Url.SiteRoot ();" How can I get my controller to not throw an Exception whenever the helper is called? I am using MVCContrib and moq for my unit tests.
I am thinking of implementing some kind of a check in the helper but it feel like the MVCContrib framework or the moq should be able to handle this so that I don't need to add Exception code in my helpers just to be able to pass the unit tests.
You can see the Helper code here:-
namespace System.Web.Mvc {
public static class UrlHelpers {
public static string SiteRoot(HttpContextBase context) {
return SiteRoot(context, true);
}
public static string SiteRoot(HttpContextBase context, bool usePort) {
var Port = context.Request.ServerVariables["SERVER_PORT"];
if (usePort) {
if (Port == null || Port == "80" || Port == "443")
Port = "";
else
Port = ":" + Port;
}
var Protocol = context.Request.ServerVariables["SERVER_PORT_SECURE"];
if (Protocol == null || Protocol == "0")
Protocol = "http://";
else
Protocol = "https://";
var appPath = context.Request.ApplicationPath;
if (appPath == "/")
appPath = "";
var sOut = Protocol + context.Request.ServerVariables["SERVER_NAME"] + Port + appPath;
return sOut;
}
public static string SiteRoot(this UrlHelper url) {
return SiteRoot(url.RequestContext.HttpContext);
}
public static string SiteRoot(this ViewPage pg) {
return SiteRoot(pg.ViewContext.HttpContext);
}
public static string SiteRoot(this ViewUserControl pg) {
var vpage = pg.Page as ViewPage;
return SiteRoot(vpage.ViewContext.HttpContext);
}
public static string SiteRoot(this ViewMasterPage pg) {
return SiteRoot(pg.ViewContext.HttpContext);
}
public static string GetReturnUrl(HttpContextBase context) {
var returnUrl = "";
if (context.Request.QueryString["ReturnUrl"] != null) {
returnUrl = context.Request.QueryString["ReturnUrl"];
}
return returnUrl;
}
public static string GetReturnUrl(this UrlHelper helper) {
return GetReturnUrl(helper.RequestContext.HttpContext);
}
public static string GetReturnUrl(this ViewPage pg) {
return GetReturnUrl(pg.ViewContext.HttpContext);
}
public static string GetReturnUrl(this ViewMasterPage pg) {
return GetReturnUrl(pg.Page as ViewPage);
}
public static string GetReturnUrl(this ViewUserControl pg) {
return GetReturnUrl(pg.Page as ViewPage);
}
}
}
Этот код выглядит немного сложным. Я думаю, что это делает то же самое, и его будет намного легче протестировать. (Я не уверен, зачем это нужно.)
public string FullApplicationPath(HttpRequestBase request)
{
var path = request.Url.AbsoluteUri.Replace(request.Url.AbsolutePath,string.Empty);
if (!string.IsNullOrEmpty(request.Url.Query))
{
path = path.Replace(request.Url.Query, string.Empty);
}
return path + request.ApplicationPath;
}
Вы, наверное, поняли, что причина, по которой вы получаете исключения из ваших методов расширения, связана с нереализованными свойствами или методами для имитируемых объектов, например Запрос на HttpContextBase или RequestContext на UrlHelper.
Взгляните на некоторые из стратегий, опубликованных здесь , чтобы узнать, как имитировать вызовы методов расширения. Лично я предпочитаю эту стратегию , которая потребует от вас рефакторинга методов расширения для обеспечения возможности их замены во время выполнения.
Например, вместо:
public static class UrlHelperExtensions
{
public static string GetReturnUrl(this UrlHelper helper)
{
return // your implementation of GetReturnUrl here
}
}
У вас будет:
public interface IUrlHelperExtensions
{
string GetReturnUrl(UrlHelper helper);
}
public static class UrlHelperExtensions
{
public static IUrlHelperExtensions Extensions(this UrlHelper target)
{
return UrlHelperExtensionFactory(target);
}
static UrlExtensions
{
UrlHelperExtensionFactory = () => new DefaultUrlHelperExtensionStrategy();
}
public static Func UrlHelperExtensionFactory { get; set; }
}
public DefaultUrlHelperExtensionStrategy : IUrlHelperExtensions
{
public string GetReturnUrl(UrlHelper helper)
{
return // your implementation of GetReturnUrl here
}
}
Вам нужно будет изменить способ вызова методов расширения с urlHelper.GetReturnUrl () на urlHelper.Extensions (). GetReturnUrl (), а во время модульного тестирования вы можете установить UrlHelperExtensions.UrlHelperExtensionFactory на фиктивный объект, но таким образом вы можете управлять поведением методов расширения во время тестирования.
Как пишет @Jeremy Frey, вы получаете исключения, потому что не можете заглушить / подделать некоторые важные части HttpContext.
Как насчет использования:
Request.Url.GetLeftPart(System.UriPartial.Authority)
вместо того, чтобы пытаться построить логику для построения URL самостоятельно? Если я правильно помню, он должен правильно подобрать протокол и порт, а также любой виртуальный каталог, сайт и т. Д.