Может ли autopper генерировать URL? - PullRequest
6 голосов
/ 21 июня 2011

Я бы хотел, чтобы autopper генерировал 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.

Я что-то упустил?Или это просто плохая идея хотеть сделать это в первую очередь?

Обновление: Дополнительный фон

Я исследую альтернативные способы создания URL для MVCпредставления с целью сделать обслуживание приложений ASP.NET MVC максимально простым.Генерация URL при отображении моделей просмотра является одной из альтернатив.Это легко проверить и очистить вид.Это также способствовало бы повторному использованию представления в некоторых случаях.Испытывая эту идею, я столкнулся с кирпичной стеной, в которой AutoMapper не смог принять какой-либо (динамический) контекст для операции Map.

Ответы [ 3 ]

7 голосов
/ 21 июня 2011

Я бы сказал, что это не работа 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 лайнер!:)

4 голосов
/ 19 сентября 2012

Хотя этот подход вызывает множество проблем с тестируемостью, можно делать то, что вы хотите ... используя HttpContext.Current.Request.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, которую он удалит.

2 голосов
/ 02 апреля 2014

Просто подумал, что поделюсь своими выводами по этой теме ... Я решил проблему следующим образом с помощью пользовательского 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";
    }
}

Вы можете создать подкласс ObjectToUrlConverter для любого объекта, который вы хотите преобразовать в URL. Затем создайте карту для каждого объекта, который вы хотите преобразовать в URL:

Mapper.CreateMap<SomeEntity, string>().ConvertUsing<SomeEntityToUrlConverter>();

И, наконец, карта следующим образом. Url является экземпляром UrlHelper.

Mapper.Map<SourceObject[], DestinationObject[]>(items, opts => opts.Items.Add("Url", Url));

Любое свойство в SourceObject, имеющее тип SomeEntity, теперь может быть надлежащим образом преобразовано в свойство строки назначения в виде URL-адреса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...