|
| 1 | +--- |
| 2 | +title: Use DateTimeOffset in a DateTimePicker and Grid |
| 3 | +description: An example on how to bind a DateTimeOffset model value to a DateTimePicker and grid. |
| 4 | +type: how-to |
| 5 | +page_title: Use DateTimeOffset Model values in a DateTimePicker and Grid |
| 6 | +slug: datetimepicker-datetimeoffset-bind-to-model |
| 7 | +tags: datetimepicker, model, value, datetimeoffset, grid, filter |
| 8 | +res_type: kb |
| 9 | +--- |
| 10 | + |
| 11 | +## Environment |
| 12 | + |
| 13 | +<table> |
| 14 | + <tr> |
| 15 | + <td>Product</td> |
| 16 | + <td>DateTimePicker for {{ site.product_long }}, Grid for {{ site.product_long }} </td> |
| 17 | + </tr> |
| 18 | +</table> |
| 19 | + |
| 20 | + |
| 21 | +## Description |
| 22 | + |
| 23 | +The DateTimeOffset structure represents a new date-time data structure which defines a point relative to the UTC time zone. However, neither databases nor JS are able of storing this structure as is since the DateTimeOffset is serialized as an object. On the other hand, the {{ site.product_short }} components which use dates strongly depend on the JavaScript Date type API which means that they need to work with a JavaScript [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). |
| 24 | + |
| 25 | +The default MVC binder is capable of binding a DateTimeOffset only if the submitted parameter is in the 2017-04-17T05:04:18.070Z format. In other words, if the {{ site.product_short }} components implement the DateTimeOffset overload, their use will be limited to only the above format or a custom binder would be required. |
| 26 | + |
| 27 | +## Solution |
| 28 | + |
| 29 | +Map database models with DateTimeOffset fields to view models with DateTime fields and use those view models in the UI for ASP.NET MVC and Core components. [AutoMapper](https://automapper.org/) is a popular third-party library that can map the models as shown below |
| 30 | + |
| 31 | +* Install AutoMapper from NuGet Package Manager or from the package manager console:. |
| 32 | + |
| 33 | +``` |
| 34 | + PM> Install-Package AutoMapper |
| 35 | +``` |
| 36 | + |
| 37 | +{% if site.core %} |
| 38 | +Upon a successful installation, the `csproj` file should include a similar package: |
| 39 | + |
| 40 | +```html |
| 41 | + <PackageReference Include="AutoMapper" Version="9.0.0" /> |
| 42 | + <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" /> |
| 43 | +``` |
| 44 | +{% else %} |
| 45 | + |
| 46 | +Upon a successful installation, the `packages.config` file should include a similar package: |
| 47 | + |
| 48 | +```html |
| 49 | + <package id="AutoMapper" version="7.0.1" targetFramework="net45" /> |
| 50 | +``` |
| 51 | +{% endif %} |
| 52 | + |
| 53 | +* Add a Mapping profile class that inherits from `AutoMapper.Profile` and list the required mappings. |
| 54 | + |
| 55 | +```MappingProfile.cs |
| 56 | + public class MappingProfile : Profile |
| 57 | + { |
| 58 | + public MappingProfile() |
| 59 | + { |
| 60 | + CreateMap<Car, CarViewModel>(); |
| 61 | + CreateMap<CarViewModel, Car>(); |
| 62 | + CreateMap<DateTime, DateTimeOffset>(); |
| 63 | + CreateMap<DateTimeOffset, DateTime>(); |
| 64 | + } |
| 65 | + } |
| 66 | +``` |
| 67 | +```DataBaseModel |
| 68 | + public class Car |
| 69 | + { |
| 70 | + public DateTimeOffset ProductionDate { get; set; } |
| 71 | + } |
| 72 | +``` |
| 73 | +```ViewModel |
| 74 | + public class CarViewModel |
| 75 | + { |
| 76 | + public DateTime ProductionDate { get; set; } |
| 77 | + } |
| 78 | +``` |
| 79 | +```Controller |
| 80 | + using AutoMapper; |
| 81 | +
|
| 82 | + public class HomeController : Controller |
| 83 | + { |
| 84 | + private readonly IMapper mapper; |
| 85 | +
|
| 86 | + {% if site.core %} |
| 87 | + public HomeController(IMapper mapper, CarsService service) |
| 88 | + { |
| 89 | + this.mapper = mapper; |
| 90 | + this.service = service; |
| 91 | + } |
| 92 | + {% else %} |
| 93 | + public HomeController() |
| 94 | + { |
| 95 | + if(mapper == null) |
| 96 | + { |
| 97 | + var mappingConfig = new MapperConfiguration(mc => |
| 98 | + { |
| 99 | + mc.AddProfile(new MappingProfile()); |
| 100 | + }); |
| 101 | + mapper = mappingConfig.CreateMapper(); |
| 102 | + } |
| 103 | + } |
| 104 | + {% endif %} |
| 105 | +
|
| 106 | + // to bind the model to any UI for ASP.NET Date/Time picker in the Index.cshtmls view |
| 107 | + public ActionResult Index() |
| 108 | + { |
| 109 | + return View(mapper.Map<CarViewModel>(cars.FirstOrDefault())); |
| 110 | + } |
| 111 | +
|
| 112 | + // to use DateTimeOffset in the context of the Ajax() bound grid |
| 113 | + public ActionResult AllCars([DataSourceRequest] DataSourceRequest request) |
| 114 | + { |
| 115 | + // map the database models to the viewmodels |
| 116 | + var result = cars.Select(car => mapper.Map<CarViewModel>(car)); |
| 117 | + // call the ToDataSourceResult() extension method over the mapped collection |
| 118 | + return Json(result.ToDataSourceResult(request)); |
| 119 | + } |
| 120 | + } |
| 121 | +``` |
| 122 | + |
| 123 | +For the complete implementation refer to {% if site.core %}[this GitHub project](https://github.com/telerik/ui-for-aspnet-core-examples/tree/master/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/DateTimeOffset).{% else %} [this GitHub project](https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/general/DateTimeOffset).{% endif %} |
0 commit comments