WCF MTOM вложение, как установить тип контента - PullRequest
0 голосов
/ 24 ноября 2018

Мне нужно установить конкретный тип контента (application / pdf) для двоичной части в привязке, настроенной для MTOM.

Есть ли что-нибудь в конфигурации или в коде, которые я могу сделать, чтобы установить тип контента?Для файловой части это всегда «Content-Type: application / octet-stream»

Config:

<binding name="FileTransferServicesBinding"
 closeTimeout="00:01:00" openTimeout="00:01:00"
 receiveTimeout="00:10:00" sendTimeout="00:01:00"
 messageEncoding="Mtom" transferMode="Buffered"
 maxBufferSize="67108864" maxReceivedMessageSize="67108864">
 <security mode="Transport" />
</binding>

То, что в данный момент отправлено службе.Составной заголовок для файла должен быть application / pdf вместо application / octetstream

POST https://somewebservice HTTP/1.1
MIME-Version: 1.0
Authorization: Basic authhash
SOAPAction: ""
Host: webservicehost
Content-Length: 24517
Expect: 100-continue
Accept-Encoding: gzip, deflate


--uuid:b8366a06-3ecc-4bc4-9809-8c87ad459981+id=1
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header>[The soapmessageitself]</s:Envelope>
--uuid:b8366a06-3ecc-4bc4-9809-8c87ad459981+id=1
Content-ID: <http://tempuri.org/1/636787311873257476>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream // This must be application/pdf

%PDF-1.4
%    
1 0 obj
<</Type /Catalog/Pages 2 0 R>> ...

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Когда времени стало мало, я решил эту проблему, вручную создавая вызов мыла.Поскольку в этом вопросе есть щедрость, я отмечу ответчика, который делает то же самое, но используя библиотеки WCF, как правильный ответ.Пример кода ниже с пометкой "byteContent.Headers.Add (" Content-Type "," application / pdf; name = test.pdf ");"что мне нужно было сделать с WCF

static HttpClient client;
static object mutex = new object();
static HttpClient Client
{
    get
    {
        if (client == null)
        {
            lock (mutex)
            {
                if (client == null)
                {
                    client = new HttpClient();
                    client.DefaultRequestHeaders.Add("MIME-Version", "1.0");
                    client.DefaultRequestHeaders.Add("SOAPAction", "\"\"");
                    client.DefaultRequestHeaders.ConnectionClose = true;
                    client.DefaultRequestHeaders.ExpectContinue = false;
                    client.DefaultRequestHeaders.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(Username + ":" + Password)));
                }
            }
        }

        return client;
    }
}

public static TResponse Send<TResponse>(string endpoint, string payload, byte[] file)
{
    string boundary = Guid.NewGuid().ToString("N");
    MultipartContent multipart = new MultipartContent("related", boundary);

    multipart.Headers.Remove("Content-Type");
    multipart.Headers.TryAddWithoutValidation("Content-Type", "multipart/related; boundary=\"" + boundary + "\"");
    multipart.Add(new StringContent(payload, Encoding.UTF8, "text/xml"));

    ByteArrayContent byteContent = new ByteArrayContent(file);
    byteContent.Headers.Remove("Content-Type");
    byteContent.Headers.Add("Content-Type", "application/pdf; name=test.pdf");
    byteContent.Headers.Add("Content-Transfer-Encoding", "binary");
    byteContent.Headers.Add("Content-ID", "<test.pdf>");
    byteContent.Headers.Add("Content-Disposition", "attachment; name=\"test.pdf\"; filename=\"test.pdf\"");

    multipart.Add(byteContent);

    var result = Client.PostAsync(endpoint, multipart).Result;
    result.EnsureSuccessStatusCode();

    var resultString = result.Content.ReadAsStringAsync().Result;
    TResponse resultTyped = XmlHelper.ToObject<TResponse>(resultString);
    return resultTyped;
}
0 голосов
/ 25 ноября 2018

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

OperationContext
  .Current
  .OutgoingMessageHeaders
  .Add ("Content-Type", "application/pdf" );

Не уверен на 100%, но сначала вам может потребоваться очистить любой существующий исходящий заголовок Content-Type.Я не думаю, что имеет значение, что ваше сообщение закодировано в MTOM.Это теоретически прозрачно.

Также ... просто спрашиваю ... зачем разрешать буферизованное сообщение размером 64 МБ, если потоковое сообщение требует гораздо меньше памяти для передачи ... и, вероятно, будет таким же быстрым или быстрым?Вы в значительной степени гарантируете лучшую производительность в сильно загруженном сервисе.

Обновление :

Если вам повезло использовать привязку веб-API-типа (WebHttpBinding) ... вы можете довольно легко транслировать свой контент, указав тип контента.Это не так уж и отличается от того, что я положил в моем ответе выше, но, как вы ответили, эти заголовки идут не туда.

Вместо этого должно быть:

WebOperationContext
  .Current
  .OutgoingResponse
  .ContentType = "application/pdf";

Здесь есть фантастическая статья / пример здесь , которая полностью развивает идею ... в соответствии с вашими целями.

Если вы привязаны к более старой привязке мыла, то вам, вероятно, нужно написать собственный кодировщик сообщений.Техника достаточно проста (если утомительна).Основная идея заключается в том, что вы можете взять на себя управление написанием тела сообщения способами, которые соответствуют вашим потребностям.

Сам кодировщик тривиален.Образец, который обходит это, будет утомительной частью.Пользовательский кодировщик происходит от абстрактного MessageEncoder .Важные вещи, которые нужно сделать, это переопределить свойства ContentType, MediaType, MessageVersion и методы ReadMessage и WriteMessage.Существуют варианты методов ReadMessage и WriteMessage для работы с потоковыми и буферизованными сообщениями.

Уродливая часть - это шаблон, который вы должны написать для развертывания вашего кодировщика.У вас есть фабрика кодировщиков и пользовательский элемент привязки.Не ужасно, но шумно.В примере пакета кода здесь ... есть пара примеров целого шарика воска (включая заводскую опору и поддержку связующего элемента), что может сэкономить вам некоторое время.

...