路由:Datetime参数传递为null/empty [英] Routing: Datetime parameter passing as null/empty

查看:82
本文介绍了路由:Datetime参数传递为null/empty的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

控制器需要两个属性.但是,其中之一( datetime )变为null.

Two attributes are needed for a Controller. However, one of them (datetime) goes as null.

路由

Routing

合并了新的路由,因此Controller可以接收两个属性:

A new routing was incorporated so the Controller could receive two attributes:

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            "RequestHistorial",
            "HechosLiquidadors/Details/{id:int}/{date:datetime}",
            defaults: new { controller = "HechosLiquidadors", action = "Details" });
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

datetime 参数没有格式限制或其他任何内容.

The datetime parameter doesn't have a format restriction or anything.

数据发送方式

How the data is sent

这是发送参数的视图:

<table class="table table-bordered table-hover table-striped" id="LiquidacionesList">
<thead>
    <tr>
        {...}
        <th>Resultados</th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model)
    {
        <tr>
            {...}
            <td>
                <div class="btn-group">
                    <a asp-action="Details" asp-route-id="@item.StoreID" 
                    asp-route-date="@item.FechaLFinLiq" 
                    class="btn btn-default">Consultar</a>
                </div>
           </td>
        </tr>

此表由foreach构造而成,该foreach会遍历模型的每个元素,最后的按钮将接收所需的属性,并使用asp-route-id/date发送这些属性.注意:该表的构造就很好.显示所有需要的数据.

This table is constructed with a foreach which iterates thru each element of the model and the button at the end receives the attributes needed and using asp-route-id/date these are sent. Note: The table is constructed just fine. All the desired data is shown.

结果

The result

单击按钮时,这是显示的网址:

When the button is clicked this is the web address that is shown:

http://localhost:60288/HechosLiquidadors/Details/13?date = 21%2F11%2F2017%200%3A00%3A00

对于此部分: date = 21%2F11%2F2017%200%3A00%3A00 我认为日期将发送给控制器.但是,当我执行此操作时:

For this part: date=21%2F11%2F2017%200%3A00%3A00 I assume the date is going to the controller. However, when I execute this:

public async Task<IActionResult> Details(int? id, DateTime date)
{
    return Content(id + "/" + date);
}

结果是: 11/01/01/0001 0:00:00

我认为格式化传递给Controller的日期是否有问题?我一直在寻找没有运气的答案.预先感谢!

I believe is a problem with formatting the date that is passing to the Controller? I've been looking for an answer with no luck. Thanks in advance!

更新

似乎问题在于Get方法如何采用此日期.看起来Get方法期望给定另一种格式,因此它将日期声明为空.

It seems like the problems is in how the Get method takes this date. It looks like the Get method expects another format that the one is given and thus it declares the date as null.

将继续更新.

推荐答案

在ASP.NET Core 2中,GET请求和日期存在相同的问题.如果要覆盖应用程序中的默认行为,以便它使用服务器GET和POST请求的默认日期格式请参见下文.在解析日期(例如使用TryParseExact等)方面可能有改进的余地,请注意,这不包括可空的日期时间.

I had the same problem with GET requests and dates in ASP.NET Core 2. If you want to override the default behaviour across the app so it uses the servers default date format for both GET and POST requests see below. Possible room for improvement around parsing the date (ie using TryParseExact etc) and note this doesn't cover nullable datetimes.

此代码很大程度上基于 https://docs.microsoft.com/zh-cn/aspnet/core/mvc/advanced/custom-model-binding

This code is heavily based on https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding

public class DateTimeModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        // Specify a default argument name if none is set by ModelBinderAttribute
        var modelName = bindingContext.BinderModelName;
        if (string.IsNullOrEmpty(modelName))
        {
            modelName = bindingContext.ModelName;
        }

        // Try to fetch the value of the argument by name
        var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);

        if (valueProviderResult == ValueProviderResult.None)
        {
            return Task.CompletedTask;
        }

        bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

        var value = valueProviderResult.FirstValue;

        // Check if the argument value is null or empty
        if (string.IsNullOrEmpty(value))
        {
            logger.Debug($"{modelName} was empty or null");
            return Task.CompletedTask;
        }

        if (!DateTime.TryParse(value, out DateTime date))
        {
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "Invalid date or format.");
            return Task.CompletedTask;
        }

        bindingContext.Result = ModelBindingResult.Success(date);
        return Task.CompletedTask;
    }
}

public class DateTimeModelBinderProvider : IModelBinderProvider
{
    private readonly IModelBinder binder = new DateTimeModelBinder();

    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        //Could possibly inspect the context and apply to GETs only if needed?
        return context.Metadata.ModelType == typeof(DateTime) ? binder : null;
    }
}

然后在启动类">"ConfigureServices"方法中

Then in the StartUp Class > ConfigureServices Method

services.AddMvc(options =>
    {
        //Forces Dates to parse via server format, inserts in the binding pipeline as first but you can adjust it as needed
        options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider());
    });

这篇关于路由:Datetime参数传递为null/empty的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆