0

我们的数据库中有一个并发检查字段,它是一个 SQL 时间戳。

如果我使用剃刀视图

@Html.HiddenFor(m => m.DatabaseRowVersion)

它编码为 Base64 字符串并在保存操作中绑定回我的模型。

如果我通过 Json 请求获得该字段

Json(queryable.Select(f => new { DatabaseRowVersion = f.DatabaseRowVersion }))

那么生成的 Json 是一个 8 字段字节数组,我无法在 Save 操作中将其绑定回我的模型。有什么方法可以让 Linq to Entities 在序列化之前将字段选择为 Base64 字符串?

我的解决方案是一个看起来很脏的 JavaScript 函数,用于将 8 个字段字节数组转换为 Base64 字符串,但这并不漂亮,我宁愿原始 Json 请求返回已经编码的字段。我尝试过的一切都给了我一个不受支持的 Linq to Entities 函数异常。我不想在内存中做这件事,我想找到某种 Entities.Functions 风格让它在 SQL 服务器上发生。

我不介意这样做的另一种方法是,如果可以让 jQuery 以某种方式发布保存请求,该方式会将 8 字段字节数组绑定到模型中的 byte[],但我尝试过的一切都不起作用。我已经在帖子上尝试了所有传统的:true 和 contentType: "application/json; charset=utf-8",但没有成功,就像在 Ajax 帖子中成功绑定数组的其他操作一样。它似乎不像其他数组那样工作,因为模型绑定器似乎期望 Base64 字符串而不是模型上 byte[] 字段的字节数组。

4

1 回答 1

0

我不确定您是否仍在寻找答案,但我设法通过将字节数组转换为字符串并返回来解决此问题:

string stringValue = System.Convert.ToBase64String(byteSource);
Byte[] byteValue = System.Convert.FromBase64String(stringSource);

对于您的情况,您可以创建一个 ViewModel 并使用AutoMapper在您的模型(具有字节数组时间戳)和视图模型(具有字符串时间戳)之间进行映射。

最后,您将使用您的 ViewModel 创建您的视图,并在更新时将您的 ViewModel 映射回您的模型并从那里更新。这样,您的隐藏字段将是一个字符串,并且您不会遇到现在遇到的问题。

Automapper 在 Byte 数组到 String 之间没有隐式转换方法,因此您必须为您的转换器实现类似的东西:

public class ByteArrayTypeConverter : ITypeConverter<string, Byte[]>
    {
        public Byte[] Convert(ResolutionContext context)
        {
            string source = (string)context.SourceValue;
            if (source == null)
            {
                source = "";
            }

            Byte[] returnValue = System.Convert.FromBase64String(source);

            return returnValue;
        }
    }

    public class StringTypeConverter : ITypeConverter<Byte[], string>
    {
        public string Convert(ResolutionContext context)
        {
            Byte[] source = (Byte[])context.SourceValue;

            string returnValue = System.Convert.ToBase64String(source);

            return returnValue;
        }
    }

您的 Mapping 初始化程序看起来像这样:

Mapper.CreateMap<string, Byte[]>().ConvertUsing(new ByteArrayTypeConverter());
Mapper.CreateMap<Byte[], string>().ConvertUsing(new StringTypeConverter());
Mapper.CreateMap<YourViewModel, YourModel);
Mapper.CreateMap<YourModel, YourViewModel>();

希望这可以帮助。

于 2013-04-28T17:06:54.610 回答