自动映射程序是否可以生成url';s
本文关键字:url 映射程序 是否 | 更新日期: 2023-09-27 18:00:06
我希望automapper为视图模型生成URL。例如,这是我的数据对象:
public class User
{
public int Id { get; set; }
public int Name { get; set; }
}
视图模型看起来像这样:
public class UserListItem
{
public string Name { get; set; }
public string EditUrl { get; set; }
}
我希望使用为应用程序定义的路由生成EditUrl
属性。
类似这样的东西:
listIten.EditUrl = Url.Action("Edit", "UserController", new { id = user.Id });
似乎没有办法让AutoMapper做到这一点。没有RequestContext、UrlHelper或任何可用于映射表达式的东西,在调用Mapper.Map.时,我也没有找到任何传递上下文的方法
我是不是错过了什么?还是一开始就想这么做只是个坏主意?
更新:附加背景
我正在研究为MVC视图生成URL的替代方法,目的是使ASP.NET MVC应用程序维护尽可能简单。在映射视图模型时生成URL是备选方案之一。测试和清理视图很容易。在某些情况下,它还将促进视图的可重用性。在尝试这个想法时,我遇到了AutoMapper无法接受Map
操作的任何类型(动态)上下文的问题。
我认为这不是AutoMapper的工作。
路由是特定于ASP.NET的,AutoMapper实际上只适用于对象映射。它没有HTTP上下文的可见性(也不应该),所以它不能完成。
如果你想在多个地方"重用"这个逻辑,为什么不创建一个强类型的HTML助手呢?
public static MvcHtmlString EditUserLinkForModel<UserListItem>(this HtmlHelper<UserListItem> htmlHelper)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
return urlHelper.Action("Edit",
"UserController",
new { id = htmlHelper.ViewData.Model.UserId });
}
视图:
@Html.EditUserLinkForModel()
尽管这可能有些过头了。这是1行!:)
尽管这种方法会导致大量的可测试性问题,但可以随心所欲。。。利用HttpContext.Current.RequestContext.
Mapper.CreateMap<Sample1, Sample2>().ForMember(
destination => destination.Url, options => options.MapFrom(source => new UrlHelper(HttpContext.Current.Request.RequestContext).Content(source.Url)));
这会使测试变得困难,但您可以通过注入一个提供UrlHelper的类来解决这个问题。然后,如果URL帮助程序可以被模拟出来,那么您的测试问题就会得到缓解,或者至少可以消除对HttpContext的依赖。
我只是想分享我对这个主题的发现。。。我使用自定义TypeConverter(AutoMapper 3.1.1)解决了以下问题:
public abstract class ObjectToUrlConverter<Source> : ITypeConverter<Source, string>
{
public string Convert(ResolutionContext context)
{
UrlHelper Url = (UrlHelper)context.Options.Items["Url"];
string result = null;
if (context.SourceValue != null)
{
result = Url.Link(GetRouteName(), GetControllerName(), GetIdentifier((Source)context.SourceValue));
}
return result;
}
public abstract object GetIdentifier(Source sourceObject);
public abstract string GetRouteName();
public abstract string GetControllerName();
}
public class SomeEntityToUrlConverter : ObjectToUrlConverter<SomeEntity>
{
public override object GetIdentifier(SomeEntity sourceObject)
{
return sourceObject.Id;
}
public override string GetRouteName()
{
return "someRouteName";
}
public override string GetControllerName()
{
return "someControllerName";
}
}
您可以为任何要转换为URL的对象子类ObjectToUrlConverter。接下来,为您希望转换为URL:的每个对象创建Map
Mapper.CreateMap<SomeEntity, string>().ConvertUsing<SomeEntityToUrlConverter>();
最后,绘制如下图。Url
是UrlHelper的实例。
Mapper.Map<SourceObject[], DestinationObject[]>(items, opts => opts.Items.Add("Url", Url));
SourceObject中SomeEntity类型的任何属性现在都可以正确地转换为目标字符串属性,如URL。