3

В настоящее время я создаю службу ASP.NET MVC WebAPI, для которой я хочу, чтобы небольшая часть двоичных данных отправлялась в цепочке. Метод в этом приложении вызывается через POST, а тело содержит фактические данные. Запрос используется для описания некоторых свойств данных в теле (например, как он кодируется).Принятие параметра байтового массива в API MVC как Base64

Интересно, можно ли принять параметр байтового массива в виде строки в кодировке base64 в строке запроса.

В качестве примера у меня есть этот код:

using System.Text; 
using System.Web.Http; 

namespace WebApplication2.Controllers 
{ 
    public class ByteArrayController : ApiController 
    { 
     public string Get([FromUri] byte[] myarray) 
     { 
      var strbResult = new StringBuilder(); 
      foreach (byte byteValue in myarray) 
      { 
       strbResult.AppendLine(byteValue.ToString() + " "); 
      } 
      return strbResult.ToString(); 
     } 
    } 
} 

Затем я хочу, чтобы иметь возможность отправить MyArray параметр следующим образом:

http://.../api/ByteArray/Get?myarray=MTIzNA%3D%3D

Пожалуйста, не возражаете именования, это просто простой пример.

Теперь я знаю, что массивы могут быть отправлены с использованием того же параметра несколько раз в строке запроса (например, MyArray = 1 & MyArray = 2 & MyArray = 3), но я хотел бы принять его как в кодировке Base64.

Я искал атрибут, чтобы указать, как декодировать массив, но не смог найти такой атрибут.

Конечно, я могу изменить код, чтобы принять строку, а затем преобразовать ее в массив байтов, но я предпочитаю делать это прозрачно, если это возможно.

ответ

6

В конце концов я нашел интересную статью о модели связующих веществ, которые позволили мне реализовать выше:

http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

Для моего решения я создал модель связующего для «базового 64-байтовых массивов»:

using System; 
using System.Web.Http.ModelBinding; 
using System.Web.Http.ValueProviders; 

namespace WebApplication2.Models 
{ 
    /// <summary> 
    /// Model binder for byte-arrays that are sent as base 64 strings. 
    /// </summary> 
    public class ModelBinderWithBase64Arrays : IModelBinder 
    { 
     public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext) 
     { 
      if (bindingContext.ModelType == typeof(byte[])) 
      { 
       ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
       string valueAsString = val.RawValue as string; 
       try 
       { 
        bindingContext.Model = Convert.FromBase64String(valueAsString); 
        return true; 
       } 
       catch 
       { 
        return false; 
       } 
      } 
      else 
      { 
       return false; 
      } 
     } 
    } 
} 

Затем я зарегистрировал его как связующее устройство по умолчанию в WebApiConfig, так что мне не нужно явно указывать его тип в параметре в контроллере. Я добавил следующие строки кода в начале метода регистр в WebApiConfig:

// Register model binder for base 64 encoded byte arrays 
var provider = new SimpleModelBinderProvider(typeof(byte[]), new ModelBinderWithBase64Arrays()); 
config.Services.Insert(typeof(ModelBinderProvider), 0, provider); 

Наконец я изменить метод действий, чтобы сделать его использовать эту модель по умолчанию связующее для Byte [] параметра путем добавления [ModelBinder] атрибут (с помощью которого можно также установить конкретную модель связующего вещества):

public string Get([ModelBinder] byte[] myarray) 

Теперь я могу просто использовать Base64 кодированное значение и принимается в виде массива байтов.

Хотя это решение требует добавления атрибута [ModelBinder], он позволяет освобождать место, где используется связующее устройство, и по-прежнему обеспечивать максимально возможную прозрачность.

Это же решение может быть использовано и для других данных, а также, например, для пользовательских значений даты.

Смежные вопросы