.net核心自定义模型绑定

时间:2016-09-03 21:14:52

标签: asp.net-core-mvc model-binding

我有一个模型,如

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="tableList-top">
    <tr class="tableListforstickymenu">
        <td class="tableList-TD-first">alpha</td>
        <td class="tableList-TD-first">bravo</td>
        <td class="tableList-TD-first">charlie</td>
        <td class="tableList-TD-first">delta</td>
        <td class="tableList-TD-first">echo</td>
    </tr>
</table>

<table class="tableList">
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>

<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>

<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>

<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>

<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>

<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>
<tr class="tableList">
<td class="tableList-TD-first">content_a</td>
<td class="tableList-TD-first">content_b</td>
<td class="tableList-TD-first">content_c</td>
<td class="tableList-TD-first">content_d</td>
<td class="tableList-TD-first">content_e</td>
</tr>

</table>

使用自定义模型绑定器一切都很好。我试图实现一个模型绑定器而不是任何地方 - 我来自的资源是 https://www.youtube.com/watch?v=qDRORgoZxZU(将null模型返回给控制器)​​

http://intellitect.com/custom-model-binding-in-asp-net-core-1-0/(控制器在构造函数上死亡)

http://hotzblog.com/asp-net-vnext-defaultmodelbinder-and-automatic-viewmodel-string-trim/(甚至无法在.net-core名称空间中找到MutableObjectModelBinder)

理想情况下,我想要跟踪ModelBinder设置的属性。

public class MyModel
{
  public MyObject myObject {get;set;}
}

public class MyObject
{
  public string FirstName {get;set;}
  public string LastName {get;set;}
}

当ModelBinder为每个正在设置的属性创建对象时,它会将其添加到ModifiedProperties列表中。

1 个答案:

答案 0 :(得分:0)

这是解决方案。您需要实现IModelBinderProvider和IModelBinder

public class EntityFrameworkModelBinderProvider : IModelBinderProvider
{    
  public IModelBinder GetBinder(ModelBinderProviderContext context)
  {       
    //We only want to invoke the CustomeBinder on IBaseEntity classes
    if (context.Metadata.ContainerType != null && context.Metadata.ContainerType.GetInterfaces().Contains(typeof(SurgeOne.Core.IBaseEntity)))
    {
    //We only create the custom binder on value types. E.g. string, guid, etc
    if (context.Metadata.ModelType.GetTypeInfo().IsValueType ||
        context.Metadata.ModelType == typeof(System.String))
    {
      return new EntityFrameworkModelBinder();
    }        
  }
  return null;        
}

}

和IModelBinder

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

    //Get the value
    var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    if (valueProviderResult == ValueProviderResult.None)
    {
      // no entry
      return Task.CompletedTask;
    }

    //Set the value -- not sure what this does
    bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);

    //Set the value -- this has to match the property type.
    System.ComponentModel.TypeConverter typeConverter = System.ComponentModel.TypeDescriptor.GetConverter(bindingContext.ModelType);
    object propValue = typeConverter.ConvertFromString(valueProviderResult.FirstValue);
    bindingContext.Result = ModelBindingResult.Success(propValue);

    //Code to track changes. 

    return Task.CompletedTask;
  } //BindModelAsync
}