自定义类型在asp net core mvc控制器方法中

时间:2017-05-09 19:45:00

标签: asp.net-mvc controller

我在MVC 6应用程序中创建了以下类型:

public class EncryptedType
{
    ...
}

我有一个控制器方法如下:

public IActionResult Index(EncryptedType id)
{
    ...
}

所以给定的url会是这样的:

http://localhost/Area1/Controller1/Index/fgf23237dsd

EncryptedType类可以处理到字符串的转换。

目前,id默认为无参数构造函数值。我需要做些什么才能使url上的字符串id自动转换为实例?

当然我可以使用字符串,但我觉得有一个显式类型来表示方法中的类型更明确。

2 个答案:

答案 0 :(得分:0)

这应该是开箱即用的。 例如,如果这是EncryptedType:

public class EncryptedType
{
    public string Id {get; set;}
    public string Name {get; set;}
}

然后,如果您的查询字符串如下所示:

http://localhost:5000/Index?Id=1&Name=MyName

查询字符串中的数据将自动解析为此类的实例。

使用除默认构造函数之外的其他构造函数来实现该类是不可能的。 请查看文档:

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding

其中有一节说明如下:

  

为了发生绑定,类必须具有公共默认值   要绑定的构造函数和成员必须是公共可写属性。   当模型绑定发生时,类将仅使用实例化   公共默认构造函数,然后可以设置属性。

答案 1 :(得分:0)

好的,我猜今天我的googling头,所以能够通过一些Stack Overflows和Microsoft docs。接线基本上有4个部分。这些是:

  1. IModelBinder实施
  2. IModelBinderProvider实施
  3. Mvc服务注册选项
  4. Controller Action上的属性
  5. IModelBinder实施

    using System;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc.ModelBinding;
    
    public class EncryptedTypeModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
    
            if (bindingContext.ModelType == typeof(EncryptedType))
            {
                EncryptedType decodedEncryptedTypeParameter;
    
                ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.FieldName);
                string theStringToConvertToEncryptedType = value.FirstValue;
    
                // add the custom convert from string to your type here, and set on the bindingContext.Result.  We still return 
                // this value from the method wrapped in a Task.
                if (EncryptedType.TryParse(theStringToConvertToEncryptedType, out decodedEncryptedTypeParameter))
                {
                    bindingContext.Result = ModelBindingResult.Success(decodedEncryptedTypeParameter);
                }
                else
                {
                    bindingContext.Result = ModelBindingResult.Failed();
                }
    
                return Task.FromResult(bindingContext.Result);
            }
    
            return Task.FromResult(ModelBindingResult.Failed());
        }
    }
    

    IModelBinderProvider实施

    using Microsoft.AspNetCore.Mvc.ModelBinding;
    
    public class EncryptedTypeModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            return new EncryptedTypeModelBinder();
        }
    }
    

    Mvc服务注册选项

    services.AddMvc().AddMvcOptions(a => 
        a.ModelBinderProviders.Add(new EncryptedTypeModelBinderProvider()));
    

    控制器操作上的属性

    public IActionResult Index(
        [ModelBinder(BinderType = typeof(EncryptedTypeModelBinder))] EncryptedType id)