WCF: (MTOM) ¿hay alguna manera de cambiar el esquema utilizado en xop: URI de referencia el contenido generado por la WCF?

StackOverflow https://stackoverflow.com/questions/2280025

  •  21-09-2019
  •  | 
  •  

Pregunta

WCF utiliza para http://tempuri/1/number Content-ID referencias URI al manejar peticiones fluían masa máxima de despegue.

¿Hay alguna manera cómo forzar WCF para utilizar un diferentes referencias Content-ID para el xop:? Incluya

Antecedentes del problema:

Estoy construyendo un cliente .NET para la masa máxima de despegue permitido servicio web JAX WS java que maneja grandes cargas de datos transmitido. Tengo hechos a mano los contactos de servicio y de datos (el WSDL generado contratos no eran correctas y no permitió que el streaming).

El problema es que el servicio web (WS JAX) no recibe el cuerpo de la petición que contiene los datos.

Se recibe datos que se transfieren en las cabeceras.

Hemos construido un cliente en java para el WS -. Éste funciona

He capturado y comparado el tráfico HTTP al emitir peticiones de Java y WCF, y la única diferencia está en cómo se genera la referencia de ID de contenido al publicar los datos de varias partes:

  • WCF utiliza http://tempuri/1/... referencias Content-ID que producen en valor codificado, como href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928"

  • cliente Java utiliza "e-mail al estilo" URI, como href="cid:3f3ec388-8cd9-47aa-a603-fb1bc17935b8@example.jaxws.sun.com"

Estos rendimiento en el siguiente xop-incluye (Data es el único elemento en el cuerpo jabón) ( XOP incluye la especificación )


//WCF:
<Data>
   <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928" />
</Data>

//JAVA:
<Data>
    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:3f3ec388-8cd9-47aa-a603-fb1bc17935b8@example.jaxws.sun.com"/>
</Data>

más adelante, en los datos de varias partes, el contenido se hace referencia por sin codificar contenido-ID:

--uuid:7e166bb7-042f-4ba3-b6ef-98fbbc21244b+id=1
Content-ID: <http://tempuri.org/1/634019957020047928>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream

Creo que hay puede de un error en el marco de servicios web JAX y no es el reconocimiento de referencias URI de Content-ID urlencoded generados WCF-+.

¿Hay alguna manera cómo forzar WCF para utilizar un diferentes referencias Content-ID para el xop:? Incluya


EDIT:. He encontrado el XmlMtomWriter que tiene el método GenerateUriForMimePart, esta se utiliza para generar contenido-IDs

public static string GenerateUriForMimePart(int index)
{
    return string.Format(CultureInfo.InvariantCulture, 
"http://tempuri.org/{0}/{1}", new object[] { index, DateTime.Now.Ticks });
}

No parece que la generación de identificación es de ninguna manera reemplazable.

Un problema similar se describe aquí, la respuesta dada no ayuda: http://social.msdn.microsoft.com/Forums/en/wcf/thread/f90affbd-f431-4602-a81d-cc66c049e351

¿Fue útil?

Solución

Asnwering a mí mismo después de una larga investigación:. No es posible sin reimplementar todo el XmlMtomWriter y otras capas y preocupaciones en WCF relacionados - casi todo lo que implica la puesta en práctica MTOM es interno

Otros consejos

Sé que es una cuestión de edad. Pero me encuentro ante el mismo problema hace dos días.

He encontrado una manera que funciona pero es un truco muy muy sucio (lo sé. Pensé en no publicar aquí, pero tal vez sería ayudar a alguien.) Con suerte no me culpa de eso.

El contentId está formateado con el uso de CultureInfo.InvariantCulture. No he encontrado una manera oficial su sustitución por una costumbre CultureInfo. Pero con la ayuda de la reflexión lo tengo funcionando. La siguiente aplicación es sólo para .Net 4.0.

public class NoTempUriInvariantCultureInfo : CultureInfo, ICustomFormatter
{
   private static CultureInfo originalCulture;
   private static object originalCultureLock;
   private static int enableCounter;

   private NoTempUriInvariantCultureInfo(CultureInfo invariantCulture)
      : base(invariantCulture.Name)
   {
      originalCulture = invariantCulture;
   }

   public static void Enable()
   {
      if(originalCultureLock == null)
         originalCultureLock = new object();

      lock (originalCultureLock)
      {
         if (enableCounter == 0)
         {
            var mInvCultField = typeof (CultureInfo).GetField("s_InvariantCultureInfo", BindingFlags.NonPublic | BindingFlags.Static);
            mInvCultField.SetValue(null, new NoTempUriInvariantCultureInfo(CultureInfo.InvariantCulture));
         }
         enableCounter++;
      }
   }

   public static void Disable()
   {
      lock (originalCulture)
      {
         if (enableCounter == 0)
            return;

         enableCounter--;
         if (enableCounter == 0)
         {
            var mInvCultField = typeof (CultureInfo).GetField("s_InvariantCultureInfo", BindingFlags.NonPublic | BindingFlags.Static);
            mInvCultField.SetValue(null, NoTempUriInvariantCultureInfo.originalCulture);
         }
      }
   }

   public override object GetFormat(Type formatType)
   {
      var result = originalCulture.GetFormat(formatType);
      return result ?? this;
   }

   public string Format(string format, object arg, IFormatProvider formatProvider)
   {
      if (format == null)
         return System.Text.RegularExpressions.Regex.Replace(arg.ToString().Replace("http%3A%2F%2Ftempuri.org%2F1%2F", ""), "http[:][/][/]tempuri[.]org[/][0-9]+[/]*", "");
      return String.Format("{0:" + format + "}", arg);
   }
}

Cómo activo mi propia "InvariantCulture" sólo ante una llamada de WCF.

NoTempUriInvariantCultureInfo.Enable();
try
{
    // make your call
}
finally
{
    NoTempUriInvariantCultureInfo.Disable();
}

CultureInfo.InvariantCulture es un objeto de estado global. Habilitación de mi propia InvariantCulture afecta cada otro hilo. Una vez más, se trata de un truco sucio. Pero funciona.

Tanto de la XOP incluye muestras que indicó son correctos y aceptable de acuerdo con la W3C. Me refiero a ellos como el formato de URL y el formato de correo electrónico, respectivamente.

No soy un desarrollador de Java, pero recuerdo un problema similar al conectarse a un servicio web en particular JAVA. Recuerdo que exista un error en un comunicado de JAVA particular, y después de ellos (los desarrolladores de Java) actualizado a la siguiente versión de lanzamiento, este problema simplemente se fueron. Me gustaría poder dar más detalles, pero en ese momento, había suficientes problemas para mí dirigirme de mi extremo del alambre y estaba contento de tener uno menos punto del registro de defectos.

//WCF: using URL format
<Data>
   <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634019957020047928" />
</Data>

//JAVA: using EMAIL format
<Data>
    <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:3f3ec388-8cd9-47aa-a603-fb1bc17935b8@example.jaxws.sun.com"/>
</Data>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top