自动映射程序是否可以生成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操作的任何类型(动态)上下文的问题。

自动映射程序是否可以生成url';s

我认为这不是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。