I would like automapper to generate URL's for a view model. For example, this is my data object:
public class User
{
public int Id { get; set; }
public int Name { get; set; }
}
The view model looks something like this:
public class UserListItem
{
public string Name { get; set; }
public string EditUrl { get; set; }
}
I would like the EditUrl
property to be generated using the routes defined for the application.
Something like this:
listIten.EditUrl = Url.Action("Edit", "UserController", new { id = user.Id });
There seems to be no way to get AutoMapper to do this. There is no RequestContext, UrlHelper or anything available for mapping expressions and I haven't found any way to pass in context when invoking Mapper.Map.
Am I missing something? Or is it just a bad idea to want to do this in the first place?
Update: Additional background
I'm investigating alternative ways of generating URLs for MVC views with the aim of making ASP.NET MVC application maintenance as easy as possible. Generating URLs while mapping the viewmodels is one of the alternatives. It's easy to test and cleans up the view. It would also promote view re-usability in some cases. While trying out this idea I ran into a brick wall with AutoMapper not being able to accept any kind of (dynamic) context for a Map
operation.
I would argue this isn't AutoMapper's job.
Routing is ASP.NET specific, AutoMapper's really only good for object mapping. It has no visibility of the HTTP Context (nor should it), so it can't be done.
If you want to "re-use" this logic across multiple places, why not create a strongly-typed HTML helper?
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 });
}
View:
@Html.EditUserLinkForModel()
Although even that's probably overkill. It's a 1 liner! :)
Although this approach causes a host of testability issues it is possible to do what you want... utilizing 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)));
This would make testing difficult but you can get around that by injecting a class that provides the UrlHelper. Then if the URL helper can be mocked out then your testing issues are mitigated or at least the dependency on HttpContext it removed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With