问:
How to debug aws lambda functions written in node js
We have been developing AWS Lambda functions in Node JS for a few months. Can we debug, i.e. step through the Node JS code as we can with .Net C# code in Visual Studio?</p>

答:
IDE-based development tools are not available by default for many Lambda functions. There are some plugins, such as the Visual Studio support introduced by AWS on their blog at https://aws.amazon.com/blogs/developer/aws-lambda-support-in-visual-studio/, but these will have varying levels of feature sets and support.

In order to test Lambda using step debugging, you'll need to focus on two domains - the hardware on which it runs, and the way in which your Lambda function is invoked. The hardware is challenging to emulate, as AWS keeps the particulars of the machine instances that run your lambda functions secret. As such, when it comes to emulating hardware, you'll simply need to keep within what's reasonable for your language and operating system - make sure that the correct run time is installed (as in, don't install NodeJS 4.X when you're working with the version 6 runtime), make sure you don't exceed storage requirements (AMIs for Lambda get 500 MB of temporary storage space in /tmp), and ensure you're not saving any state locally prior to runs of your code.

Once you've nailed down your machine requirements (or decided to pass on them as your code doesn't do any hardware-specific work), then you'll need to write a test harness to invoke your AWS Lambda function. This test harness serves as an entry point for your debugger, and while it is most likely not 100% accurate with respect to how AWS invokes Lambda (for example, the context parameter contains information on your current Lambda invocation, which will by nature vary between executions), it gets you to the point where you can invoke all of your standard coding support tools.

Note: the following simple test harness is written for Node.JS, but you can adapt the concepts to the runtime in which your Lambda executes

A Simple Test Harness for AWS Lambda (Node.js)

The first thing we'll do is create a new file - debug.js - and import the handler function prototype. Assuming you've defined your handler in handler.js, and called it handler, you do that as follows:

var handler = require('./handler.js').handler;

Next, we need to invoke the handler function. As I alluded to above, each of the parameters has a different purpose. The first parameter to the handler -event - has details of the event causing the invocation. Note: This also includes your function arguments. The second parameter, as we discussed, contains information on the context in which your function is running. There's also a third parameter, callback, that can be used to invoke a callback upon completion of your Lambda execution. Review the AWS docs here: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

So for our purposes, for a simple test harness, we just need to send the parameters through in the event parameter. We'll leave the context and callback parameters alone for now (with a minor modification, more on that below), but if you want to provide extra data there that your function relies upon that's fine - just make sure it doesn't conflict with any of the automated data put there in AWS. So we define the parameter hash, and invoke the function, using the following code in debug.js:

```<code>var parameters = {
    "key1":"val1",
    "object" :{},
    // other keys as necessary
};

handler(parameters, {succeed:function(result){
    console.log("success: ", JSON.stringify(result, null, 2));
    process.exit(0);
}, fail:function(error){
    console.error("error: ", error);
    process.exit(1);
}});
</code>```

This code does a few interesting things:

It overloads the context object with a success and fail handler. You can wrap these in an "if" statement, and invoke them in your Lambda code using context.succeed(message) or context.fail(error). These are not officially supported by Lambda, but are instead used as a workaround in our code to get access to success/fail behavior

Handlers call process.exit() with the appropriate error code. This allows you to chain your execution into CI/CD tools, or any other batch processing tools that use process exit code as control flow

Once you've written this simple test harness, and adapted your Lambda code to invoke the success/fail handler if they are present (something as simple as if(context.success){context.success(args);} should be sufficient), you can now invoke the lambda function using node debug.js and see the results in the console.

I've also had great luck with unit testing in my Lambda functions. As you now have an entry point, and an example of how to call the Lambda function, you should be able to write suitable unit and function tests that express all of your functionality.

A quick note on shortcomings

As I mentioned, this approach isn't perfect. Here are a few problems with the test harness that could potentially arise:

We haven't done any emulation of the context object. You can see the parameters available in the context object at http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - you'll need to do some trial and error to figure out exactly what format ends up in these parameters

We have not done any machine emulation, to catch hardware issues

We've only covered Node.js functions here, other languages may have trouble adapting the callback approach

We've overloaded the context mechanism to provide our success-fail handlers. If AWS adds similarly-named member objects to the context object, this approach may run into problems

However, despite the above, you should now have the capability to use local debugging tools to test and debug your Lambda functions. We use a similar framework at Backand - https://www.backand.com - for our Lambda function development tool, and it has greatly increased our Lambda development velocity.

Body:
IDE-based development tools are not available by default for many Lambda functions. There are some plugins, such as the Visual Studio support introduced by AWS on their blog at https://aws.amazon.com/blogs/developer/aws-lambda-support-in-visual-studio/, but these will have varying levels of feature sets and support.

In order to test Lambda using step debugging, you'll need to focus on two domains - the hardware on which it runs, and the way in which your Lambda function is invoked. The hardware is challenging to emulate, as AWS keeps the particulars of the machine instances that run your lambda functions secret. As such, when it comes to emulating hardware, you'll simply need to keep within what's reasonable for your language and operating system - make sure that the correct run time is installed (as in, don't install NodeJS 4.X when you're working with the version 6 runtime), make sure you don't exceed storage requirements (AMIs for Lambda get 500 MB of temporary storage space in /tmp), and ensure you're not saving any state locally prior to runs of your code.

Once you've nailed down your machine requirements (or decided to pass on them as your code doesn't do any hardware-specific work), then you'll need to write a test harness to invoke your AWS Lambda function. This test harness serves as an entry point for your debugger, and while it is most likely not 100% accurate with respect to how AWS invokes Lambda (for example, the context parameter contains information on your current Lambda invocation, which will by nature vary between executions), it gets you to the point where you can invoke all of your standard coding support tools.

Note: the following simple test harness is written for Node.JS, but you can adapt the concepts to the runtime in which your Lambda executes

A Simple Test Harness for AWS Lambda (Node.js)

The first thing we'll do is create a new file - debug.js - and import the handler function prototype. Assuming you've defined your handler in handler.js, and called it handler, you do that as follows:

var handler = require('./handler.js').handler;

Next, we need to invoke the handler function. As I alluded to above, each of the parameters has a different purpose. The first parameter to the handler -event - has details of the event causing the invocation. Note: This also includes your function arguments. The second parameter, as we discussed, contains information on the context in which your function is running. There's also a third parameter, callback, that can be used to invoke a callback upon completion of your Lambda execution. Review the AWS docs here: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

So for our purposes, for a simple test harness, we just need to send the parameters through in the event parameter. We'll leave the context and callback parameters alone for now (with a minor modification, more on that below), but if you want to provide extra data there that your function relies upon that's fine - just make sure it doesn't conflict with any of the automated data put there in AWS. So we define the parameter hash, and invoke the function, using the following code in debug.js:

var parameters = {
    "key1":"val1",
    "object" :{},
    // other keys as necessary
};

handler(parameters, {succeed:function(result){
    console.log("success: ", JSON.stringify(result, null, 2));
    process.exit(0);
}, fail:function(error){
    console.error("error: ", error);
    process.exit(1);
}});

This code does a few interesting things:

It overloads the context object with a success and fail handler. You can wrap these in an "if" statement, and invoke them in your Lambda code using context.succeed(message) or context.fail(error). These are not officially supported by Lambda, but are instead used as a workaround in our code to get access to success/fail behavior

Handlers call process.exit() with the appropriate error code. This allows you to chain your execution into CI/CD tools, or any other batch processing tools that use process exit code as control flow

Once you've written this simple test harness, and adapted your Lambda code to invoke the success/fail handler if they are present (something as simple as if(context.success){context.success(args);} should be sufficient), you can now invoke the lambda function using node debug.js and see the results in the console.

I've also had great luck with unit testing in my Lambda functions. As you now have an entry point, and an example of how to call the Lambda function, you should be able to write suitable unit and function tests that express all of your functionality.

A quick note on shortcomings

As I mentioned, this approach isn't perfect. Here are a few problems with the test harness that could potentially arise:

We haven't done any emulation of the context object. You can see the parameters available in the context object at http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - you'll need to do some trial and error to figure out exactly what format ends up in these parameters

We have not done any machine emulation, to catch hardware issues

We've only covered Node.js functions here, other languages may have trouble adapting the callback approach

We've overloaded the context mechanism to provide our success-fail handlers. If AWS adds similarly-named member objects to the context object, this approach may run into problems

However, despite the above, you should now have the capability to use local debugging tools to test and debug your Lambda functions. We use a similar framework at Backand - https://www.backand.com - for our Lambda function development tool, and it has greatly increased our Lambda development velocity.


来源: stackexchange

问:
Copy files with MsBuild
I have a solution with two projects. One of them is a simple project that doesn't depend on any special assemblies to build. However, the application is allowed to launch an external executable (that I also own -- this is the second project of my solution). When I build the project, I would like the executable (+ dependencies such as app.config) of the external project to be copied under the target directory of my project.

How can I achieve this with MsBuild? My first idea was to add a reference to the executable (even though I don't need it to build) to copy the file. This seem a bit hacky to me.

Thanks!

P.S. Another question: Let's say that I can tell MsBuild to copy the executable. What if the executable isn't build? Can I force it to build?

答: Have you looked the MSBuild Copy Task: Copy Task ?</p>

ContentLicense: CC BY-SA 2.5

Title: Copy files with MsBuild


问:
Game services not working for app if downloaded from play store
I've been trying to get the game services working properly for so long. My problem is that game service isn't working on the version downloaded from the play store, but on the version downloaded directly from android studio the game service works perfectly. Even though both versions use the same key and have the same SHA1 code (the release SHA1 code). I checked if the SHA1 from the play store version of my app matches with the game service's SHA1 by comparing the SHA1 codes from the android-release.apk and from https://console.developers.google.com/apis/credentials/oauthclient. I doubt that the problem lies in the code of my app, because it works perfectly in the version downloaded directly from android studio.

So my question is what I could have possibly done wrong here, and how to fix it.

Thank you for reading

答: First off, I want to thank everyone who took their time to post an answer. I don't think anyone could have guessed my stupid mistake because it only applies to libGDX users. The problem was that the target sdk in the gradle .build file of BaseGameUtils was not the same as the .build file of the android module. It's amazing how such a small mistake can cost your whole weekend!</p>

ContentLicense: CC BY-SA 3.0


问:
Reactivemongo - BSONObjectID and BSONDateTime Insertion
I'm using play2.5 + play2-reactivemongo 0.12.3.

BSONObjectID is inserted as array and BSONDateTime is inserted as NumberLong on mongoDB with following codes.

```<code>> db.Example.find()
{ "_id" : { "array" : [ 89, 55, -10, 60, -40, 0, 0, -61, 0, -94, 126, 23 ] }, "created" : NumberLong("1496839744818") }
</code>```

I want BSONObjectID to be inserted as ObjectID and DateTime to be inserted as BSONDateTime.
Is it possible to do with type parameter?

TemporalModel.scala

```<code>trait TemporalModel {
  var _id: Option[BSONObjectID]
  var created: Option[DateTime]
}
</code>```

Example.scala

```<code>import org.joda.time.DateTime
...

case class Example(
  var_id: Option[BSONObjectID],
  str: String,
  var created: Option[DateTime]
) extends TemporalModel

object Example {

  //implicit val objectIdRead: Reads[BSONObjectID] =
  val objectIdRead: Reads[BSONObjectID] =
    (__ \ "$oid").read[String].map { oid =>
      BSONObjectID(oid)
  }

  //implicit val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
  val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
    def writes(objectId: BSONObjectID): JsValue = Json.obj(
      "$oid" -> objectId.stringify
    )
  }

  //implicit val dateTimeRead: Reads[DateTime] =
  val dateTimeRead: Reads[DateTime] =
    (__ \ "$date").read[Long].map { dateTime =>
      new DateTime(dateTime)
  }

  //implicit val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
  val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
    def writes(dateTime: DateTime): JsValue = Json.obj(
      "$date" -> dateTime.getMillis
    )
  }

  implicit val objectIdFormats = Format(objectIdRead, objectIdWrite)
  implicit val dateTimeFormats = Format(dateTimeRead, dateTimeWrite)
  //implicit val bsonObjectIDJsonFormat = Json.format[BSONObjectID]
  implicit val exampleJsonFormat = Json.format[Example]

  def apply(str: String): Example = {
    new Example(null, str, null)
  }
}
</code>```

BaseDAO.scala

```<code>class BaseDAO[T] {
  ...
  val collectionName: String
  lazy val collection: Future[JSONCollection] = reactiveMongoApi.database.map(_.collection(collectionName))

  def toJs[K : Writes](o: K) = Json.toJson(o).as[JsObject]

  def insert(document: T)(implicit writer: Writes[T]): Future[T] = {
    document._id = Some(BSONObjectID.generate)
    document.created = Some(DateTime.now)
    collection.flatMap(_.insert(toJs(document)))
  }
}
</code>```

ExampleDAO.scala

```<code>trait ExampleDAO extends BaseDAO[Example]

class ExampleDAOImpl @Inject() (val reactiveMongoApi: ReactiveMongoApi)
extends ExampleDAO {
  val collectionName = "example"
}
</code>```

答:
The problem is that you have too many implicits in-scope. However, since those are resolved in the macro, there seems to be no compilation error.

What you should do:

remove all implicit modifiers in front of your Reads and Writes for BSONObjectID and DateTime

remove bsonObjectIDJsonFormat (which has same type as objectIdFormats, so this should not be allowed by the compiler)

Body:
I'm using play2.5 + play2-reactivemongo 0.12.3.

BSONObjectID is inserted as array and BSONDateTime is inserted as NumberLong on mongoDB with following codes.

> db.Example.find()
{ "_id" : { "array" : [ 89, 55, -10, 60, -40, 0, 0, -61, 0, -94, 126, 23 ] }, "created" : NumberLong("1496839744818") }

I want BSONObjectID to be inserted as ObjectID and DateTime to be inserted as BSONDateTime.
Is it possible to do with type parameter?

TemporalModel.scala

trait TemporalModel {
  var _id: Option[BSONObjectID]
  var created: Option[DateTime]
}

Example.scala

import org.joda.time.DateTime
...

case class Example(
  var_id: Option[BSONObjectID],
  str: String,
  var created: Option[DateTime]
) extends TemporalModel

object Example {

  //implicit val objectIdRead: Reads[BSONObjectID] =
  val objectIdRead: Reads[BSONObjectID] =
    (__ \ "$oid").read[String].map { oid =>
      BSONObjectID(oid)
  }

  //implicit val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
  val objectIdWrite: Writes[BSONObjectID] = new Writes[BSONObjectID] {
    def writes(objectId: BSONObjectID): JsValue = Json.obj(
      "$oid" -> objectId.stringify
    )
  }

  //implicit val dateTimeRead: Reads[DateTime] =
  val dateTimeRead: Reads[DateTime] =
    (__ \ "$date").read[Long].map { dateTime =>
      new DateTime(dateTime)
  }

  //implicit val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
  val dateTimeWrite: Writes[DateTime] = new Writes[DateTime] {
    def writes(dateTime: DateTime): JsValue = Json.obj(
      "$date" -> dateTime.getMillis
    )
  }

  implicit val objectIdFormats = Format(objectIdRead, objectIdWrite)
  implicit val dateTimeFormats = Format(dateTimeRead, dateTimeWrite)
  //implicit val bsonObjectIDJsonFormat = Json.format[BSONObjectID]
  implicit val exampleJsonFormat = Json.format[Example]

  def apply(str: String): Example = {
    new Example(null, str, null)
  }
}

BaseDAO.scala

class BaseDAO[T] {
  ...
  val collectionName: String
  lazy val collection: Future[JSONCollection] = reactiveMongoApi.database.map(_.collection(collectionName))

  def toJs[K : Writes](o: K) = Json.toJson(o).as[JsObject]

  def insert(document: T)(implicit writer: Writes[T]): Future[T] = {
    document._id = Some(BSONObjectID.generate)
    document.created = Some(DateTime.now)
    collection.flatMap(_.insert(toJs(document)))
  }
}

ExampleDAO.scala

trait ExampleDAO extends BaseDAO[Example]

class ExampleDAOImpl @Inject() (val reactiveMongoApi: ReactiveMongoApi)
extends ExampleDAO {
  val collectionName = "example"
}


问:
VB.Net Multithreading - Event Not Firing?
I've got this code, and let's say I am iterating over 100 items.  The first time I iterate over the list, the ProxyTested event fires 100 times.  Great, that was easy.

Now comes the annoying unknown bug currently giving me a headache, if only it would give me an exception too, then I could probably figure out whats going wrong much easier.

Here it is: The second time I iterate over the list, and each time after, the ProxyTested event fires 99 times.  What happened to 1 of my iterations?

P.S. For my project, Tasks throughput is much slower than spawning say 500 of my own threads, so because of that reason I don't want to use them.  Just saying that before the inevitable suggestion. It may not look so pretty, but it runs very, very fast compared to creating a list of Tasks and passing them into Task.WaitAll, which is admittedly much easier on the eyes.

P.S.S.
Also, before the use a Concurrent Collection suggestion that is also inevitable, need to use a DataTable here, because I am also using SqliteDataAdapter.Update in this project, which only takes a DataTable or array of DataRow's.

```<code>Dim counter as integer = 0
For i = 0 To ThreadCount - 1
            Dim t As New Thread(Sub()
                                Do

                                    Dim item As DataRow = Nothing
                                    Dim req As HttpWebRequest = Nothing
                                    SyncLock lock
                                        If counter > Proxies.Rows.Count Then
                                            Exit Do
                                        End If
                                        item = Proxies(counter)
                                        Interlocked.Increment(counter)
                                        Dim judge As DataRow = validJudges(rnd.Next(0, validJudges.Count))
                                        Dim proxy As String = item("ip") & ":" & item("port")

                                        req = HttpWebRequest.Create(judge("url"))
                                        req.Proxy = New WebProxy(proxy)
                                        req.Timeout = Timeout
                                        Debug.WriteLine(counter)
                                    End SyncLock

                                    Dim statusText As String = ProxyTest.GetStatus(req, "<title>AZ Environment variables 1.04</title>", externalIp)

                                    SyncLock lock
                                        item("statusText") = statusText

                                        If statusText = "Valid" Then
                                            Interlocked.Increment(ValidCount)
                                        Else
                                            Interlocked.Increment(InvalidCount)
                                        End If
                                        Interlocked.Increment(CompletedCount)
                                        RaiseEvent ProxyTested(item)
                                    End SyncLock

                                Loop
                                mre.Set()
                            End Sub)
            t.Start()
        Next
        mre.Reset()
        mre.WaitOne()
</code>```

答:
Re initializing my ManualResetEvent each time I called this method solved my problem :)

mre = New ManualResetEvent(False)

Previously mre was a global that was only initialized once during loading.

Body:
I've got this code, and let's say I am iterating over 100 items.  The first time I iterate over the list, the ProxyTested event fires 100 times.  Great, that was easy.

Now comes the annoying unknown bug currently giving me a headache, if only it would give me an exception too, then I could probably figure out whats going wrong much easier.

Here it is: The second time I iterate over the list, and each time after, the ProxyTested event fires 99 times.  What happened to 1 of my iterations?

P.S. For my project, Tasks throughput is much slower than spawning say 500 of my own threads, so because of that reason I don't want to use them.  Just saying that before the inevitable suggestion. It may not look so pretty, but it runs very, very fast compared to creating a list of Tasks and passing them into Task.WaitAll, which is admittedly much easier on the eyes.

P.S.S.
Also, before the use a Concurrent Collection suggestion that is also inevitable, need to use a DataTable here, because I am also using SqliteDataAdapter.Update in this project, which only takes a DataTable or array of DataRow's.

Dim counter as integer = 0
For i = 0 To ThreadCount - 1
            Dim t As New Thread(Sub()
                                Do

                                    Dim item As DataRow = Nothing
                                    Dim req As HttpWebRequest = Nothing
                                    SyncLock lock
                                        If counter > Proxies.Rows.Count Then
                                            Exit Do
                                        End If
                                        item = Proxies(counter)
                                        Interlocked.Increment(counter)
                                        Dim judge As DataRow = validJudges(rnd.Next(0, validJudges.Count))
                                        Dim proxy As String = item("ip") & ":" & item("port")

                                        req = HttpWebRequest.Create(judge("url"))
                                        req.Proxy = New WebProxy(proxy)
                                        req.Timeout = Timeout
                                        Debug.WriteLine(counter)
                                    End SyncLock

                                    Dim statusText As String = ProxyTest.GetStatus(req, "<title>AZ Environment variables 1.04</title>", externalIp)

                                    SyncLock lock
                                        item("statusText") = statusText

                                        If statusText = "Valid" Then
                                            Interlocked.Increment(ValidCount)
                                        Else
                                            Interlocked.Increment(InvalidCount)
                                        End If
                                        Interlocked.Increment(CompletedCount)
                                        RaiseEvent ProxyTested(item)
                                    End SyncLock

                                Loop
                                mre.Set()
                            End Sub)
            t.Start()
        Next
        mre.Reset()
        mre.WaitOne()


问:
Mapping DTO to Entity while TrackingChanges with AutoMapper and EFCore
Very new to AutoMapper and EFCore, so maybe biting off more than i can chew here, but thought i would give it a go, but failing, and maybe it aint possible, but if it is maybe someone can point me in the right direction.

I am using AutoMapper to convert my entities to a DTO, this is fine.

Now i would like to convert my DTO to an entity and have EntityFramework track all the changes (property updated, child object removed from list etc), but is this possible?

So if i have a simple PUT method, i would like to do something like this, and let automapper sort out the rest

```<code>public async Task<IActionResult> PutAsync([FromBody] MyDTO model)
{
    // GET OBJECT FROM DATABASE HERE
    var dbValue = _repos.GetMyObjectUsingId(999);

    // apply updates
    _mapper.Map<MyDTO, MyObject>(dbValue, model);

}
</code>```

答:
You can create an adapter class so your change set remains the same:
Have you DTO's inherit from an interface

Say you have a DTO:

```<code>public interface IFooDTO
{
   int Id { get; set;}
   string Name { get; set;}
}

public class FooDTO : IFooDTO
{
   public int Id { get; set;}
   public string Name { get; set; }
}
</code>```

Then you have your entity

```<code>public class FooEntity
{
   public int Id;
   public string name;
}
</code>```

Then create your adapter like so which inherits from the foo interface:

```<code>public class FooAdapter : IFooDTO
{
   FooEntity entity;
   FooAdapter(FooEntity entity)
   {
      this.entity = entity;
   }

   public int Id
   {
      get {return this.entity.Id;}
      set {/*Do nothing set by EF*/}
   }

   public string Name
   {
       get {return this.entity.Name;}
       set {this.entity.Name = value; }
   }

   public void Apply(FooDTO foo)
   {
        //I don't remember if this is the correct order but you get the gyst
        this._mapper.Map<IFooDTO, IFooDTO>(this, foo);
   }
}
</code>```

Then you just need to Map from your Idto to you dto in the mapper.

Usage:

```<code> public ActionResult PutFoo(int id, FooDTO foo)
 {
     var entity = context.Foos.FirstOrDefault(x => x.Id == id);
     var adapter = new FooAdapter(entity);
     adapter.Apply(foo);
     //Entity has been updated and has original changes
 }
</code>```

EDIT

Children Work fine just use the same adapter pattern the setter for this is a lot of code but

```<code>public BarDTO childBar
{
   get { return new BarAdapter(this.entity.Bar).ToDTO(); }
   set { new BarAdapter(this.entity.Bar).Apply(value) }
}
</code>```

Syncing Entities:

```<code>public static void Sync<TEntity, TEntityKey, TDTO>(this ICollection<TEntity> entityCollection, ICollection<TDTO> dtoCollection,
    Func<TEntity> entityConstructor, Action<TDTO, TEntity> copyAction,
    Action<TEntity> onDeleteAction,
    Func<TEntity, TEntityKey> entityKeySelector,
    Func<TDTO, TEntityKey> dtoKeySelector)
    where TEntity : class
    where TEntityKey : struct
{
    dtoCollection = dtoCollection ?? new TDTO[] { };
    except = except ?? new TEntityKey[] { };

    var dtoIds = dtoCollection.Select(dto => dtoKeySelector(dto)).ToHashSet();
    foreach (var entity in entityCollection.Where(x => false == dtoIds.Contains(entityKeySelector(x))).ToArray())
    {
        onDeleteAction(entity);
        entityCollection.Remove(entity);
    }

    var entityCollectionMap = entityCollection.ToDictionary(x => entityKeySelector(x));

    foreach (var dtoItem in dtoCollection)
    {
        TEntity entity = null;
        if (dtoKeySelector(dtoItem).HasValue)
        {
            entity = entityCollectionMap.ContainsKey(dtoKeySelector(dtoItem)) ? entityCollectionMap[dtoKeySelector(dtoItem)] : default(TEntity);

        }

        if (null == entity)
        {
            entity = entityConstructor();
            entityCollection.Add(entity);
        }
        copyAction(dtoItem, entity);
    }
}
</code>```

Body:
Very new to AutoMapper and EFCore, so maybe biting off more than i can chew here, but thought i would give it a go, but failing, and maybe it aint possible, but if it is maybe someone can point me in the right direction.

I am using AutoMapper to convert my entities to a DTO, this is fine.

Now i would like to convert my DTO to an entity and have EntityFramework track all the changes (property updated, child object removed from list etc), but is this possible?

So if i have a simple PUT method, i would like to do something like this, and let automapper sort out the rest

public async Task<IActionResult> PutAsync([FromBody] MyDTO model)
{
    // GET OBJECT FROM DATABASE HERE
    var dbValue = _repos.GetMyObjectUsingId(999);

    // apply updates
    _mapper.Map<MyDTO, MyObject>(dbValue, model);

}

Body:
You can create an adapter class so your change set remains the same:
Have you DTO's inherit from an interface

Say you have a DTO:

public interface IFooDTO
{
   int Id { get; set;}
   string Name { get; set;}
}

public class FooDTO : IFooDTO
{
   public int Id { get; set;}
   public string Name { get; set; }
}

Then you have your entity

public class FooEntity
{
   public int Id;
   public string name;
}

Then create your adapter like so which inherits from the foo interface:

public class FooAdapter : IFooDTO
{
   FooEntity entity;
   FooAdapter(FooEntity entity)
   {
      this.entity = entity;
   }

   public int Id
   {
      get {return this.entity.Id;}
      set {/*Do nothing set by EF*/}
   }

   public string Name
   {
       get {return this.entity.Name;}
       set {this.entity.Name = value; }
   }

   public void Apply(FooDTO foo)
   {
        //I don't remember if this is the correct order but you get the gyst
        this._mapper.Map<IFooDTO, IFooDTO>(this, foo);
   }
}

Then you just need to Map from your Idto to you dto in the mapper.

Usage:

 public ActionResult PutFoo(int id, FooDTO foo)
 {
     var entity = context.Foos.FirstOrDefault(x => x.Id == id);
     var adapter = new FooAdapter(entity);
     adapter.Apply(foo);
     //Entity has been updated and has original changes
 }

EDIT

Children Work fine just use the same adapter pattern the setter for this is a lot of code but

public BarDTO childBar
{
   get { return new BarAdapter(this.entity.Bar).ToDTO(); }
   set { new BarAdapter(this.entity.Bar).Apply(value) }
}

Syncing Entities:

public static void Sync<TEntity, TEntityKey, TDTO>(this ICollection<TEntity> entityCollection, ICollection<TDTO> dtoCollection,
    Func<TEntity> entityConstructor, Action<TDTO, TEntity> copyAction,
    Action<TEntity> onDeleteAction,
    Func<TEntity, TEntityKey> entityKeySelector,
    Func<TDTO, TEntityKey> dtoKeySelector)
    where TEntity : class
    where TEntityKey : struct
{
    dtoCollection = dtoCollection ?? new TDTO[] { };
    except = except ?? new TEntityKey[] { };

    var dtoIds = dtoCollection.Select(dto => dtoKeySelector(dto)).ToHashSet();
    foreach (var entity in entityCollection.Where(x => false == dtoIds.Contains(entityKeySelector(x))).ToArray())
    {
        onDeleteAction(entity);
        entityCollection.Remove(entity);
    }

    var entityCollectionMap = entityCollection.ToDictionary(x => entityKeySelector(x));

    foreach (var dtoItem in dtoCollection)
    {
        TEntity entity = null;
        if (dtoKeySelector(dtoItem).HasValue)
        {
            entity = entityCollectionMap.ContainsKey(dtoKeySelector(dtoItem)) ? entityCollectionMap[dtoKeySelector(dtoItem)] : default(TEntity);

        }

        if (null == entity)
        {
            entity = entityConstructor();
            entityCollection.Add(entity);
        }
        copyAction(dtoItem, entity);
    }
}


问:
Error consuming SOAP 1.1 operation send attachment using MTOM optimization
I'm trying to consume a SOAP service that receives a message with an attachment. With SoapUI I made the call the service with success, but using WSO2 Integrator I receive the follow response error from server:

```<code>OSB-382000: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]</faultstring><detail><con:stack-trace xmlns:con="http://www.bea.com/wli/sb/context">com.bea.wli.sb.service.handlerchain.HandlerException: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundDISIHandler.dispatch(InboundDISIHandler.java:148)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundWssPhase1DISIHandler.dispatch(InboundWssPhase1DISIHandler.java:100)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageContentHandler.dispatch(InboundMessageContentHandler.java:169)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.CheckAccessControl.dispatch(CheckAccessControl.java:65)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.UpdateInboundTransportStatistics.dispatch(UpdateInboundTransportStatistics.java:64)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageTracing.dispatch(InboundMessageTracing.java:80)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.DefaultInboundErrorHandler.dispatch(DefaultInboundErrorHandler.java:44)
    at com.bea.wli.sb.service.handlerchain.InboundHandlerChain.dispatch(InboundHandlerChain.java:134)
    at com.bea.wli.sb.transports.TransportDispatcherClient.dispatch(TransportDispatcherClient.java:91)
    at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:352)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.invokePipeline(RequestHelperBase.java:200)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet$RequestHelperWLS.invokePipeline(HttpTransportServlet.java:228)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:175)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:173)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
    at com.bea.wli.sb.util.security.SecurityUtils.executeAs(SecurityUtils.java:102)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.securedInvoke(RequestHelperBase.java:172)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.service(RequestHelperBase.java:124)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet.service(HttpTransportServlet.java:129)
    at weblogic.servlet.FutureResponseServlet.service(FutureResponseServlet.java:24)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
</code>```

I suspect that the error is due the HTTP headers, but I can't find any other reference to change those headers to look like the SoapUI ones. Some headers are equals, others not. I tried to set some header to make these same as in SoapUI, no success.

Following are the resource that I'm using (removed all logs to fit here). Payload is resumed due sensitive data, but assume that SOAP envelope generated by WSO2 Integrator is ok, since the same envelope submitted from SoapUI is received without any error from server:

Endpoint:

```<code><endpoint xmlns="http://ws.apache.org/ns/synapse" name="envio_informacao_res_dados_clinicos">
    <address uri="http://xpto.com.br/service?WSDL" format="soap11" optimize="mtom">
        <enableSec policy="wssSecurityRES"/>
    </address>
</endpoint>
</code>```

Sequence (to set the attachment to payload):

```<code><sequence xmlns="http://ws.apache.org/ns/synapse" name="attachment">
    <property name="attachmentContent" expression="get-property('ATTACHMENT_CONTENT')"/>
    <property name="attachmentContentID" expression="get-property('ATTACHMENT_CONTENT_ID')"/>
    <class name="br.com.modoagil.MTOMAttachmentFilesMediator"/>
</sequence>
</code>```

Proxy service (for test only):

```<code><?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="AttachmentFileProxyService" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="ATTACHMENT_CONTENT" expression="$body/*" />
      <property name="ATTACHMENT_CONTENT_ID" value="AnexoLaboratorio.xml" />
      <payloadFactory media-type="xml">
        <format>
          <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00" xmlns:v17="http://xpto.com.br/schemas/comum/tipos/complexos/anexos/v1.00" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
            <soapenv:Header />
            <soapenv:Body>
              <v1:requisicaoEnvioInformacaoRES>
                <v1:cabecalhoRequisicao>
                  <!-- omitted -->
                </v1:cabecalhoRequisicao>
                <v1:corpoRequisicao>
                  <v1:beneficiario>
                    <!-- omitted -->
                  </v1:beneficiario>
                  <v1:profissional>
                    <!-- omitted -->
                  </v1:profissional>
                  <v1:informacaoClinica>
                    <v17:anexoComposicao xm:contentType="application/xml" xm:expectedContentTypes="application/xml" />
                    <!-- omitted -->
                  </v1:informacaoClinica>
                </v1:corpoRequisicao>
              </v1:requisicaoEnvioInformacaoRES>
            </soapenv:Body>
          </soapenv:Envelope>
        </format>
        <args />
      </payloadFactory>
      <sequence key="attachment" />
      <header name="Action" action="remove" />
      <property name="SOAPAction" action="remove" />
      <property name="FORCE_HTTP_1.0" value="true" scope="axis2" />
      <property name="SOAPAction" value="envio_informacao_res" scope="transport" />
      <property name="Proxy-Authorization" scope="transport" expression="fn:concat('Basic ', base64Encode('ZZZZ:YYYY'))" />
      <send>
        <endpoint key="envio_informacao_res_dados_clinicos" />
      </send>
    </inSequence>
    <outSequence>
      <property name="enableMTOM" value="true" scope="axis2" />
      <send />
    </outSequence>
  </target>
</proxy>
</code>```

Custom Mediator:

```<code>import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMText;
import org.apache.axiom.soap.SOAPBody;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseException;
import org.apache.synapse.mediators.AbstractMediator;

public class MTOMAttachmentFilesMediator extends AbstractMediator {

    @Override
    public boolean mediate(final MessageContext context) {
        this.addAttachmentToRequest(context);
        return true;
    }

    private void addAttachmentToRequest(final MessageContext context) {
        final String attachmentContent = (String) context.getProperty("attachmentContent");
        final String attachmentContentID = (String) context.getProperty("attachmentContentID");

        Path tempContentFile = null;
        try {
            tempContentFile = Files.createTempFile(attachmentContentID + "-" + System.currentTimeMillis(), ".bin");
            Files.write(tempContentFile, attachmentContent.getBytes(Charset.defaultCharset()));
        } catch (final IOException e) {
            super.handleException("Error while creating attachment file: " + e.getMessage(), e, context);
        }

        if (tempContentFile == null) {
            throw new SynapseException("Temporary attachment file must not be null here");
        }

        final SOAPBody body = context.getEnvelope().getBody();
        final OMElement requisicaoEnvioInformacaoRES = body.getFirstElement();
        final OMElement corpoRequisicao = (OMElement) requisicaoEnvioInformacaoRES.getChildrenWithName(new QName("corpoRequisicao")).next();
        final OMElement informacaoClinica = (OMElement) corpoRequisicao.getChildrenWithName(new QName("informacaoClinica")).next();

        final OMFactory factory = informacaoClinica.getOMFactory();

        final OMElement anexoComposicao = (OMElement) informacaoClinica.getChildrenWithName(new QName("anexoComposicao")).next();
        final FileDataSource fileDataSource = new FileDataSource(tempContentFile.toFile());
        final DataHandler dataHandler = new DataHandler(fileDataSource);
        final OMText bynaryNode = factory.createOMText(dataHandler, true);
        bynaryNode.setContentID(attachmentContentID);
        anexoComposicao.addChild(bynaryNode);
    }

}
</code>```

SoapUI "full request/response":

```<code>POST /service?WSDL HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml"; boundary="----=_Part_10_1408830521.1496694507193"
SOAPAction: "envio_informacao_res"
Authorization: Basic omitted
MIME-Version: 1.0
Content-Length: 33427
Host: xpto.com.br.br:7300
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

------=_Part_10_1408830521.1496694507193

Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart@soapui.org>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00" xmlns:v17="http://xpto.com.br/schemas/comum/tipos/complexos/anexos/v1.00" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
    <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-CAD2037163FCADC4A5149669450719220">
                <wsse:Username>omitted</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">omitted</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">omitted==</wsse:Nonce>
                <wsu:Created>2017-06-05T20:28:27.192Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <v1:requisicaoEnvioInformacaoRES>
            <v1:cabecalhoRequisicao>
                <!-- omitted -->
            </v1:cabecalhoRequisicao>
            <v1:corpoRequisicao>
                <v1:beneficiario>
                    <!-- omitted -->
                </v1:beneficiario>
                <v1:profissional>
                    <!-- omitted -->
                </v1:profissional>
                <v1:informacaoClinica>
                    <v17:anexoComposicao xm:contentType="application/xml" xm:expectedContentTypes="application/xml">
                        <inc:Include xmlns:inc="http://www.w3.org/2004/08/xop/include" href="cid:AnexoLaboratorio.xml" />
                    </v17:anexoComposicao>
                    <!-- omitted -->
                </v1:informacaoClinica>
            </v1:corpoRequisicao>
        </v1:requisicaoEnvioInformacaoRES>
    </soapenv:Body>
</soapenv:Envelope>

------=_Part_10_1408830521.1496694507193

Content-Type: text/xml; charset=us-ascii; name=AnexoLaboratorio.xml
Content-Transfer-Encoding: 7bit
Content-ID: <AnexoLaboratorio.xml>
Content-Disposition: attachment; name="AnexoLaboratorio.xml"; filename="AnexoLaboratorio.xml"

<?xml version="1.0" encoding="UTF-8"?>
<Clinical_Summary_Events xmlns:oe="http://schemas.openehr.org/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.oceanehr.com/templates" archetype_node_id="openEHR-EHR-COMPOSITION.encounter.v1" template_id="clinical-summary-events" type="COMPOSITION" xsi:schemaLocation="http://schemas.oceanehr.com/templates templates/clinical-summary-events.xsd">
  <!-- omitted -->
</Clinical_Summary_Events>

------=_Part_10_1408830521.1496694507193--

##### RESPONSE #####

HTTP/1.1 200 OK
Server: Oracle-Traffic-Director/11.1.1.9
Date: Mon, 05 Jun 2017 20:28:30 GMT
Content-length: 3463
Content-type: text/xml; charset=UTF-8
X-oracle-dms-ecid: XeMsH1O_000000000
Via: 1.1 net-QA
Proxy-agent: Oracle-Traffic-Director/11.1.1.9

<soapenv:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><ptucsseir:respostaEnvioInformacaoRES xmlns:ptucsseir="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00"> <!-- omitted --></ptucsseir:respostaEnvioInformacaoRES></soap-env:Body></soapenv:Envelope>"
</code>```

WSO2 EI "full request/response":

```<code>POST /service?WSDL HTTP/1.0
SOAPAction: envio_informacao_res
Accept-Encoding: gzip,deflate
Proxy-Authorization: Basic omitted
Content-Type: text/xml; charset=UTF-8
Content-Length: 41934
Host: xpto.com.br:7300
Connection: Keep-Alive
User-Agent: Synapse-PT-HttpComponents-NIO

--MIMEBoundary_20282c2967f861ead2423a50af020431e31644c6c1d1eeb6

Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <0.30282c2967f861ead2423a50af020431e31644c6c1d1eeb6@apache.org>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00" xmlns:v17="http://xpto.com.br/schemas/comum/tipos/complexos/anexos/v1.00" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
    <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
            <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
                <wsse:Username>omitted</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">omitted</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">omitted</wsse:Nonce>
                <wsu:Created>2017-06-06T15:01:38.098Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <v1:requisicaoEnvioInformacaoRES>
            <v1:cabecalhoRequisicao>
                <!-- omitted -->
            </v1:cabecalhoRequisicao>
            <v1:corpoRequisicao>
                <v1:beneficiario>
                    <!-- omitted -->
                </v1:beneficiario>
                <v1:profissional>
                    <!-- omitted -->
                </v1:profissional>
                <v1:informacaoClinica>
                    <v17:anexoComposicao xm:contentType="application/xml" xm:expectedContentTypes="application/xml">
                        <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:AnexoLaboratorio.xml" />
                    </v17:anexoComposicao>
                    <!-- omitted -->
                </v1:informacaoClinica>
            </v1:corpoRequisicao>
        </v1:requisicaoEnvioInformacaoRES>
    </soapenv:Body>
</soapenv:Envelope>

--MIMEBoundary_20282c2967f861ead2423a50af020431e31644c6c1d1eeb6

Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <AnexoLaboratorio.xml>

<Clinical_Summary_Events xmlns="http://schemas.oceanehr.com/templates" xmlns:oe="http://schemas.openehr.org/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" archetype_node_id="openEHR-EHR-COMPOSITION.encounter.v1" template_id="clinical-summary-events" type="COMPOSITION" xsi:schemaLocation="http://schemas.oceanehr.com/templates templates/clinical-summary-events.xsd">
    <!-- omitted -->
</Clinical_Summary_Events>

--MIMEBoundary_20282c2967f861ead2423a50af020431e31644c6c1d1eeb6--

##### RESPONSE #####

--MIMEBoundary_00282c2967f861ea3c123a50af020431f31644c6c1d1eeb6
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <0.10282c2967f861ea3c123a50af020431f31644c6c1d1eeb6@apache.org>

<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>OSB-382000: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]</faultstring><detail><con:stack-trace xmlns:con="http://www.bea.com/wli/sb/context">com.bea.wli.sb.service.handlerchain.HandlerException: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundDISIHandler.dispatch(InboundDISIHandler.java:148)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundWssPhase1DISIHandler.dispatch(InboundWssPhase1DISIHandler.java:100)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageContentHandler.dispatch(InboundMessageContentHandler.java:169)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.CheckAccessControl.dispatch(CheckAccessControl.java:65)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.UpdateInboundTransportStatistics.dispatch(UpdateInboundTransportStatistics.java:64)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageTracing.dispatch(InboundMessageTracing.java:80)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.DefaultInboundErrorHandler.dispatch(DefaultInboundErrorHandler.java:44)
    at com.bea.wli.sb.service.handlerchain.InboundHandlerChain.dispatch(InboundHandlerChain.java:134)
    at com.bea.wli.sb.transports.TransportDispatcherClient.dispatch(TransportDispatcherClient.java:91)
    at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:352)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.invokePipeline(RequestHelperBase.java:200)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet$RequestHelperWLS.invokePipeline(HttpTransportServlet.java:228)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:175)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:173)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
    at com.bea.wli.sb.util.security.SecurityUtils.executeAs(SecurityUtils.java:102)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.securedInvoke(RequestHelperBase.java:172)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.service(RequestHelperBase.java:124)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet.service(HttpTransportServlet.java:129)
    at weblogic.servlet.FutureResponseServlet.service(FutureResponseServlet.java:24)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: com.sun.xml.ws.protocol.soap.MessageCreationException: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:319)
    at com.sun.xml.ws.api.message.MessageContextFactory.createContext(MessageContextFactory.java:130)
    at com.oracle.webservices.impl.disi.context.DISIMessageContextFactory.createContext(DISIMessageContextFactory.java:114)
    at com.oracle.webservices.impl.disi.service.DISIAdapter$2.createContext(DISIAdapter.java:227)
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundDISIHandler.dispatch(InboundDISIHandler.java:88)
    ... 47 more
Caused by: com.sun.xml.ws.streaming.XMLStreamReaderException: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.wrapException(XMLStreamReaderUtil.java:326)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.next(XMLStreamReaderUtil.java:99)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.nextContent(XMLStreamReaderUtil.java:169)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.nextElementContent(XMLStreamReaderUtil.java:104)
    at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:215)
    at com.oracle.webservices.impl.encoding.StreamDecoderImpl.decode(StreamDecoderImpl.java:64)
    at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:249)
    at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:166)
    at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:314)
    ... 51 more
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:639)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2052)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1134)
    at com.sun.xml.ws.util.xml.XMLStreamReaderFilter.next(XMLStreamReaderFilter.java:96)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.next(XMLStreamReaderUtil.java:80)
    ... 58 more
</con:stack-trace></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>
--MIMEBoundary_00282c2967f861ea3c123a50af020431f31644c6c1d1eeb6--
</code>```

So, does anyone have a similar problem to do SOAP/MTOM request with WSO2 EI/WSO2 ESB?

EDIT:

WSO2 Integration version: 6.1.1

WSO2 EI is running with default configuration, no configuration was changed, not even properties to enable MTOM in axis2.xml configuration file.

答:
Found a solution. I just add this property to the proxy:

<property name="messageType" value="multipart/related" scope="axis2"/>
```

Maybe this is not the best solution, since headers are the same as before and SoapUI apparently generate a more clean request, but now the service receive correctly the message sent by WSO2 EI.

I don't know why, but instead of send attachment in a separated "section", with a XOP inclusion - like before, as logs at question -, now WSO2 EI sends attachment inline on SOAP Envelope - looks like base 64 encoded.

For now it's OK, if this solution cause problem I create other question.

Body:
I'm trying to consume a SOAP service that receives a message with an attachment. With SoapUI I made the call the service with success, but using WSO2 Integrator I receive the follow response error from server:

OSB-382000: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]</faultstring><detail><con:stack-trace xmlns:con="http://www.bea.com/wli/sb/context">com.bea.wli.sb.service.handlerchain.HandlerException: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundDISIHandler.dispatch(InboundDISIHandler.java:148)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundWssPhase1DISIHandler.dispatch(InboundWssPhase1DISIHandler.java:100)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageContentHandler.dispatch(InboundMessageContentHandler.java:169)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.CheckAccessControl.dispatch(CheckAccessControl.java:65)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.UpdateInboundTransportStatistics.dispatch(UpdateInboundTransportStatistics.java:64)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageTracing.dispatch(InboundMessageTracing.java:80)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.DefaultInboundErrorHandler.dispatch(DefaultInboundErrorHandler.java:44)
    at com.bea.wli.sb.service.handlerchain.InboundHandlerChain.dispatch(InboundHandlerChain.java:134)
    at com.bea.wli.sb.transports.TransportDispatcherClient.dispatch(TransportDispatcherClient.java:91)
    at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:352)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.invokePipeline(RequestHelperBase.java:200)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet$RequestHelperWLS.invokePipeline(HttpTransportServlet.java:228)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:175)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:173)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
    at com.bea.wli.sb.util.security.SecurityUtils.executeAs(SecurityUtils.java:102)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.securedInvoke(RequestHelperBase.java:172)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.service(RequestHelperBase.java:124)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet.service(HttpTransportServlet.java:129)
    at weblogic.servlet.FutureResponseServlet.service(FutureResponseServlet.java:24)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)

I suspect that the error is due the HTTP headers, but I can't find any other reference to change those headers to look like the SoapUI ones. Some headers are equals, others not. I tried to set some header to make these same as in SoapUI, no success.

Following are the resource that I'm using (removed all logs to fit here). Payload is resumed due sensitive data, but assume that SOAP envelope generated by WSO2 Integrator is ok, since the same envelope submitted from SoapUI is received without any error from server:

Endpoint:

<endpoint xmlns="http://ws.apache.org/ns/synapse" name="envio_informacao_res_dados_clinicos">
    <address uri="http://xpto.com.br/service?WSDL" format="soap11" optimize="mtom">
        <enableSec policy="wssSecurityRES"/>
    </address>
</endpoint>

Sequence (to set the attachment to payload):

<sequence xmlns="http://ws.apache.org/ns/synapse" name="attachment">
    <property name="attachmentContent" expression="get-property('ATTACHMENT_CONTENT')"/>
    <property name="attachmentContentID" expression="get-property('ATTACHMENT_CONTENT_ID')"/>
    <class name="br.com.modoagil.MTOMAttachmentFilesMediator"/>
</sequence>

Proxy service (for test only):

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="AttachmentFileProxyService" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="ATTACHMENT_CONTENT" expression="$body/*" />
      <property name="ATTACHMENT_CONTENT_ID" value="AnexoLaboratorio.xml" />
      <payloadFactory media-type="xml">
        <format>
          <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00" xmlns:v17="http://xpto.com.br/schemas/comum/tipos/complexos/anexos/v1.00" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
            <soapenv:Header />
            <soapenv:Body>
              <v1:requisicaoEnvioInformacaoRES>
                <v1:cabecalhoRequisicao>

                </v1:cabecalhoRequisicao>
                <v1:corpoRequisicao>
                  <v1:beneficiario>

                  </v1:beneficiario>
                  <v1:profissional>

                  </v1:profissional>
                  <v1:informacaoClinica>
                    <v17:anexoComposicao xm:contentType="application/xml" xm:expectedContentTypes="application/xml" />

                  </v1:informacaoClinica>
                </v1:corpoRequisicao>
              </v1:requisicaoEnvioInformacaoRES>
            </soapenv:Body>
          </soapenv:Envelope>
        </format>
        <args />
      </payloadFactory>
      <sequence key="attachment" />

      <property name="SOAPAction" action="remove" />
      <property name="FORCE_HTTP_1.0" value="true" scope="axis2" />
      <property name="SOAPAction" value="envio_informacao_res" scope="transport" />
      <property name="Proxy-Authorization" scope="transport" expression="fn:concat('Basic ', base64Encode('ZZZZ:YYYY'))" />
      <send>
        <endpoint key="envio_informacao_res_dados_clinicos" />
      </send>
    </inSequence>
    <outSequence>
      <property name="enableMTOM" value="true" scope="axis2" />
      <send />
    </outSequence>
  </target>
</proxy>

Custom Mediator:

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMText;
import org.apache.axiom.soap.SOAPBody;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseException;
import org.apache.synapse.mediators.AbstractMediator;

public class MTOMAttachmentFilesMediator extends AbstractMediator {

    @Override
    public boolean mediate(final MessageContext context) {
        this.addAttachmentToRequest(context);
        return true;
    }

    private void addAttachmentToRequest(final MessageContext context) {
        final String attachmentContent = (String) context.getProperty("attachmentContent");
        final String attachmentContentID = (String) context.getProperty("attachmentContentID");

        Path tempContentFile = null;
        try {
            tempContentFile = Files.createTempFile(attachmentContentID + "-" + System.currentTimeMillis(), ".bin");
            Files.write(tempContentFile, attachmentContent.getBytes(Charset.defaultCharset()));
        } catch (final IOException e) {
            super.handleException("Error while creating attachment file: " + e.getMessage(), e, context);
        }

        if (tempContentFile == null) {
            throw new SynapseException("Temporary attachment file must not be null here");
        }

        final SOAPBody body = context.getEnvelope().getBody();
        final OMElement requisicaoEnvioInformacaoRES = body.getFirstElement();
        final OMElement corpoRequisicao = (OMElement) requisicaoEnvioInformacaoRES.getChildrenWithName(new QName("corpoRequisicao")).next();
        final OMElement informacaoClinica = (OMElement) corpoRequisicao.getChildrenWithName(new QName("informacaoClinica")).next();

        final OMFactory factory = informacaoClinica.getOMFactory();

        final OMElement anexoComposicao = (OMElement) informacaoClinica.getChildrenWithName(new QName("anexoComposicao")).next();
        final FileDataSource fileDataSource = new FileDataSource(tempContentFile.toFile());
        final DataHandler dataHandler = new DataHandler(fileDataSource);
        final OMText bynaryNode = factory.createOMText(dataHandler, true);
        bynaryNode.setContentID(attachmentContentID);
        anexoComposicao.addChild(bynaryNode);
    }

}

SoapUI "full request/response":

POST /service?WSDL HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml"; boundary="----=_Part_10_1408830521.1496694507193"
SOAPAction: "envio_informacao_res"
Authorization: Basic omitted
MIME-Version: 1.0
Content-Length: 33427
Host: xpto.com.br.br:7300
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

------=_Part_10_1408830521.1496694507193

Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart@soapui.org>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00" xmlns:v17="http://xpto.com.br/schemas/comum/tipos/complexos/anexos/v1.00" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
    <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-CAD2037163FCADC4A5149669450719220">
                <wsse:Username>omitted</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">omitted</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">omitted==</wsse:Nonce>
                <wsu:Created>2017-06-05T20:28:27.192Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <v1:requisicaoEnvioInformacaoRES>
            <v1:cabecalhoRequisicao>

            </v1:cabecalhoRequisicao>
            <v1:corpoRequisicao>
                <v1:beneficiario>

                </v1:beneficiario>
                <v1:profissional>

                </v1:profissional>
                <v1:informacaoClinica>
                    <v17:anexoComposicao xm:contentType="application/xml" xm:expectedContentTypes="application/xml">
                        <inc:Include xmlns:inc="http://www.w3.org/2004/08/xop/include" href="cid:AnexoLaboratorio.xml" />
                    </v17:anexoComposicao>

                </v1:informacaoClinica>
            </v1:corpoRequisicao>
        </v1:requisicaoEnvioInformacaoRES>
    </soapenv:Body>
</soapenv:Envelope>

------=_Part_10_1408830521.1496694507193

Content-Type: text/xml; charset=us-ascii; name=AnexoLaboratorio.xml
Content-Transfer-Encoding: 7bit
Content-ID: <AnexoLaboratorio.xml>
Content-Disposition: attachment; name="AnexoLaboratorio.xml"; filename="AnexoLaboratorio.xml"

<?xml version="1.0" encoding="UTF-8"?>
<Clinical_Summary_Events xmlns:oe="http://schemas.openehr.org/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.oceanehr.com/templates" archetype_node_id="openEHR-EHR-COMPOSITION.encounter.v1" template_id="clinical-summary-events" type="COMPOSITION" xsi:schemaLocation="http://schemas.oceanehr.com/templates templates/clinical-summary-events.xsd">

</Clinical_Summary_Events>

------=_Part_10_1408830521.1496694507193--

##### RESPONSE #####

HTTP/1.1 200 OK
Server: Oracle-Traffic-Director/11.1.1.9
Date: Mon, 05 Jun 2017 20:28:30 GMT
Content-length: 3463
Content-type: text/xml; charset=UTF-8
X-oracle-dms-ecid: XeMsH1O_000000000
Via: 1.1 net-QA
Proxy-agent: Oracle-Traffic-Director/11.1.1.9

<soapenv:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><ptucsseir:respostaEnvioInformacaoRES xmlns:ptucsseir="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00"> </ptucsseir:respostaEnvioInformacaoRES></soap-env:Body></soapenv:Envelope>"

WSO2 EI "full request/response":

POST /service?WSDL HTTP/1.0
SOAPAction: envio_informacao_res
Accept-Encoding: gzip,deflate
Proxy-Authorization: Basic omitted
Content-Type: text/xml; charset=UTF-8
Content-Length: 41934
Host: xpto.com.br:7300
Connection: Keep-Alive
User-Agent: Synapse-PT-HttpComponents-NIO

--MIMEBoundary_20282c2967f861ead2423a50af020431e31644c6c1d1eeb6

Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <0.30282c2967f861ead2423a50af020431e31644c6c1d1eeb6@apache.org>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xpto.com.br/schemas/servico/envio/informacao/res/v1.00" xmlns:v17="http://xpto.com.br/schemas/comum/tipos/complexos/anexos/v1.00" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
    <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
            <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
                <wsse:Username>omitted</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">omitted</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">omitted</wsse:Nonce>
                <wsu:Created>2017-06-06T15:01:38.098Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <v1:requisicaoEnvioInformacaoRES>
            <v1:cabecalhoRequisicao>

            </v1:cabecalhoRequisicao>
            <v1:corpoRequisicao>
                <v1:beneficiario>

                </v1:beneficiario>
                <v1:profissional>

                </v1:profissional>
                <v1:informacaoClinica>
                    <v17:anexoComposicao xm:contentType="application/xml" xm:expectedContentTypes="application/xml">
                        <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:AnexoLaboratorio.xml" />
                    </v17:anexoComposicao>

                </v1:informacaoClinica>
            </v1:corpoRequisicao>
        </v1:requisicaoEnvioInformacaoRES>
    </soapenv:Body>
</soapenv:Envelope>

--MIMEBoundary_20282c2967f861ead2423a50af020431e31644c6c1d1eeb6

Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <AnexoLaboratorio.xml>

<Clinical_Summary_Events xmlns="http://schemas.oceanehr.com/templates" xmlns:oe="http://schemas.openehr.org/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" archetype_node_id="openEHR-EHR-COMPOSITION.encounter.v1" template_id="clinical-summary-events" type="COMPOSITION" xsi:schemaLocation="http://schemas.oceanehr.com/templates templates/clinical-summary-events.xsd">

</Clinical_Summary_Events>

--MIMEBoundary_20282c2967f861ead2423a50af020431e31644c6c1d1eeb6--

##### RESPONSE #####

--MIMEBoundary_00282c2967f861ea3c123a50af020431f31644c6c1d1eeb6
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <0.10282c2967f861ea3c123a50af020431f31644c6c1d1eeb6@apache.org>

<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>OSB-382000: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]</faultstring><detail><con:stack-trace xmlns:con="http://www.bea.com/wli/sb/context">com.bea.wli.sb.service.handlerchain.HandlerException: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundDISIHandler.dispatch(InboundDISIHandler.java:148)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundWssPhase1DISIHandler.dispatch(InboundWssPhase1DISIHandler.java:100)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageContentHandler.dispatch(InboundMessageContentHandler.java:169)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.CheckAccessControl.dispatch(CheckAccessControl.java:65)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.UpdateInboundTransportStatistics.dispatch(UpdateInboundTransportStatistics.java:64)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.InboundMessageTracing.dispatch(InboundMessageTracing.java:80)
    at com.bea.wli.sb.service.handlerchain.handlers.AbstractHandler.dispatch(AbstractHandler.java:131)
    at com.bea.wli.sb.service.handlerchain.handlers.DefaultInboundErrorHandler.dispatch(DefaultInboundErrorHandler.java:44)
    at com.bea.wli.sb.service.handlerchain.InboundHandlerChain.dispatch(InboundHandlerChain.java:134)
    at com.bea.wli.sb.transports.TransportDispatcherClient.dispatch(TransportDispatcherClient.java:91)
    at com.bea.wli.sb.transports.TransportManagerImpl.receiveMessage(TransportManagerImpl.java:352)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.invokePipeline(RequestHelperBase.java:200)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet$RequestHelperWLS.invokePipeline(HttpTransportServlet.java:228)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:175)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase$1.run(RequestHelperBase.java:173)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
    at com.bea.wli.sb.util.security.SecurityUtils.executeAs(SecurityUtils.java:102)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.securedInvoke(RequestHelperBase.java:172)
    at com.bea.wli.sb.transports.http.generic.RequestHelperBase.service(RequestHelperBase.java:124)
    at com.bea.wli.sb.transports.http.wls.HttpTransportServlet.service(HttpTransportServlet.java:129)
    at weblogic.servlet.FutureResponseServlet.service(FutureResponseServlet.java:24)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: com.sun.xml.ws.protocol.soap.MessageCreationException: Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:319)
    at com.sun.xml.ws.api.message.MessageContextFactory.createContext(MessageContextFactory.java:130)
    at com.oracle.webservices.impl.disi.context.DISIMessageContextFactory.createContext(DISIMessageContextFactory.java:114)
    at com.oracle.webservices.impl.disi.service.DISIAdapter$2.createContext(DISIAdapter.java:227)
    at com.bea.wli.sb.service.disi.handlerchain.handlers.InboundDISIHandler.dispatch(InboundDISIHandler.java:88)
    ... 47 more
Caused by: com.sun.xml.ws.streaming.XMLStreamReaderException: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.wrapException(XMLStreamReaderUtil.java:326)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.next(XMLStreamReaderUtil.java:99)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.nextContent(XMLStreamReaderUtil.java:169)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.nextElementContent(XMLStreamReaderUtil.java:104)
    at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:215)
    at com.oracle.webservices.impl.encoding.StreamDecoderImpl.decode(StreamDecoderImpl.java:64)
    at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:249)
    at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:166)
    at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:314)
    ... 51 more
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:639)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2052)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1134)
    at com.sun.xml.ws.util.xml.XMLStreamReaderFilter.next(XMLStreamReaderFilter.java:96)
    at com.sun.xml.ws.streaming.XMLStreamReaderUtil.next(XMLStreamReaderUtil.java:80)
    ... 58 more
</con:stack-trace></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>
--MIMEBoundary_00282c2967f861ea3c123a50af020431f31644c6c1d1eeb6--

So, does anyone have a similar problem to do SOAP/MTOM request with WSO2 EI/WSO2 ESB?

EDIT:

WSO2 Integration version: 6.1.1

WSO2 EI is running with default configuration, no configuration was changed, not even properties to enable MTOM in axis2.xml configuration file.

Body:
Found a solution. I just add this property to the proxy:

<property name="messageType" value="multipart/related" scope="axis2"/>

Maybe this is not the best solution, since headers are the same as before and SoapUI apparently generate a more clean request, but now the service receive correctly the message sent by WSO2 EI.

I don't know why, but instead of send attachment in a separated "section", with a XOP inclusion - like before, as logs at question -, now WSO2 EI sends attachment inline on SOAP Envelope - looks like base 64 encoded.

For now it's OK, if this solution cause problem I create other question.

ContentLicense: CC BY-SA 4.0


问:
w3c markup validator ampersand (&) error
Is there any workaround for the w3c validation error for an & present in urls or some other place in HTML markup?

It says:

& did not start a character reference. (& probably should have been escaped as &.)

The ampersand in my case is a part of a url for gravatar thumbnail. This is the problematic part of a url:

c91588793296e2?s=50&d=http%3A%2F%.

答:
should be:

c91588793296e2?s=50&d=http%3A%2F%.

notice the &

I know it feels wonky, but ampersands have to be encoded as html entities, which are confusingly denoted with ampersands.

Body:
should be:

c91588793296e2?s=50&amp;d=http%3A%2F%.

notice the &amp;

I know it feels wonky, but ampersands have to be encoded as html entities, which are confusingly denoted with ampersands.


问:
Where does one get Piranha CMS's SQL Server CE sdf data file from?
I am trying to add Piranha CMS to a simple website. Being Entity Framework and following the getting started guide I thought that the database would be created. I chose to use the file based database which the system is obviously not finding. Am I missing some step?

See error below:

The database file cannot be found. Check the path to the database. [ Data Source = C:...\App_Data\Piranha.sdf ]

Update 7/6/2017: I installed SQL CE Tools and manually created an sdf file with the name matching the connection string. The app now showed an error about a missing table which I was able to "fix" by setting 'showDBErrors' to false as I found here. I will try installing again from the CMS's home page.

答:
So, for me right now the answer is, you have to create your own database (unless someone provides a different/better answer).
I went ahead and manually created the sdf file in my App_Data folder. After doing that the following error appeared:

https://github.com/PiranhaCMS/Piranha/issues/429

The error with the missing table sysparam seems to be only related with this setting at this point:
<showDBErrors value="false" />
 Setting it to false solved the problem.

Finally I was able to run the setup and be redirected to the login page. Only that I couldn't pass the login page.
The answer to that particular problem was to remove the modules section from web config in my case. Removing the section altogether presents other questions on it's own, but it got me to actually being able to create content.


Title: how to divided two data frame col by col according the same ID?

Body:
I have two data frames with different length as follow:

> df1

V1         V2          V3      V4   V5      V6  V7  V8  V9  V10 V11 V12 V13 V14 V15
chr1    1572489     1575053     -   SSU72   182 464 288 437 521 646 490 213 411 535
chr1    231532572   231536297   -   TAF5L   28  62  28  48  12  41  31  32  19  22
chr1    97305156    97306558    -   DPYD    13  18  9   17  20  22  1   2   2   3
chr1    10380576    10386010    +   KIF1B   274 324 99  183 223 153 270 250 314 190

> df2

V1         V2           V3      V4  V5      V6  V7  V8  V9  V10 V11 V12 V13 V14 V15
chr1    1551810      1552304    -   SSU72   12  32  274 99  68  5   113 58  187 156
chr1    231526495   231528472   -   TAF5L   48  29  64  50  36  40  83  26  73  51
chr1    10453959    10459017    +   KIF1B   152 346 891 419 476 752 420 242 477 550
chr1    10455753    10459010    +   KIF1B   152 345 887 412 470 748 420 237 473 540
chr1    222514442   222516274   +   MARK1   2   6   5   6   2   10  2   6   3   14

I would like to create some ratios according with the name in V5. So for example, as SSU72 is in both data frames, I would like to create the ratio for V6 to V15 like this:

(df1$V6/df2$V6, df1$V7/df2$V7.....df1V15/df2$V15)

I've tried to create some loops but I am lost.

Body:
We can do a merge based on the 'V5' column, then get the columns that have names end with .x and .y separately, and  divide

dfN <- merge(df1[-(1:4)], df2[-(1:4)], by = "V5")
dfN1 <- cbind(dfN[1], dfN[grepl("\\.x", names(dfN))]/dfN[grepl("\\.y", names(dfN))])
names(dfN1) <- sub("\\.x$", "", names(dfN1))
dfN1
#V5         V6         V7        V8        V9       V10         V11       V12      V13       V14       V15
#1 KIF1B  1.8026316  0.9364162 0.1111111 0.4367542 0.4684874   0.2034574 0.6428571 1.033058 0.6582809 0.3454545
#2 KIF1B  1.8026316  0.9391304 0.1116122 0.4441748 0.4744681   0.2045455 0.6428571 1.054852 0.6638478 0.3518519
#3 SSU72 15.1666667 14.5000000 1.0510949 4.4141414 7.6617647 129.2000000 4.3362832 3.672414 2.1978610 3.4294872
#4 TAF5L  0.5833333  2.1379310 0.4375000 0.9600000 0.3333333   1.0250000 0.3734940 1.230769 0.2602740 0.4313725


问:
Conforming to NSCoding
I cannot for the life of me figure out why I am getting the error that this class does not conform to NSCoding protocols.  Maybe another set of eyes would help.  I have tried to add comments to make it clear what each func is doing.  </p>

```<code>import Foundation
import UIKit

class Search: NSObject, NSCoding {

// Global Variables
var articlePicture: UIImage!
var articleTitle: String

// MARK: Public Init
init(articlePicture: UIImage, articleTitle: String) {
    self.articlePicture = articlePicture
    self.articleTitle = articleTitle
}

// Required NSCoding Protocol
required convenience init?(coder decoder: NSCoder) {
    guard let articlePicture = decoder.decodeObject(forKey: "articlePicture") as? UIImage,
        let articleTitle = decoder.decodeObject(forKey: "articleTitle") as? String
        else { return nil }

    self.init(
        articlePicture: articlePicture,
        articleTitle: articleTitle
    )
}

// Required NSCoding Protocal
func encodeWithCoder(coder: NSCoder) {
    coder.encode(self.articlePicture, forKey: "articlePicture")
    coder.encode(self.articleTitle, forKey: "articleTitle")
}

// Initialize [Search]
static var searches = [Search]()

static func getSearches() -> [Search]{
    return searches
}

static func setSearch(search: Search){
    searches.append(search)
}

// NSUserDefaults Searches Array funcs
static func saveSearches(){
    let searchData = NSKeyedArchiver.archivedData(withRootObject: searches)
    UserDefaults.standard.set(searchData, forKey: "searches")
}

static func loadSearches() -> [Search]{
    let searchData = UserDefaults.standard.object(forKey: "searches") as? NSData

    if let searchData = searchData {
        searches = (NSKeyedUnarchiver.unarchiveObject(with: searchData as Data) as? [Search])!
        return searches
    }
    return searches
}
}
</code>```

答:
In Swift 4 there is another way to encode/decode classes. Now you'll only have to conform to the protocol Codable. No more need to write all your encode and decodes and it supports classes without NSObject & enums & structs.

```<code>final class Search: Codable {

}
</code>```

For more information, read https://developer.apple.com/documentation/swift/codable

Title: Conforming to NSCoding

Body:
I cannot for the life of me figure out why I am getting the error that this class does not conform to NSCoding protocols.  Maybe another set of eyes would help.  I have tried to add comments to make it clear what each func is doing.

import Foundation
import UIKit

class Search: NSObject, NSCoding {

// Global Variables
var articlePicture: UIImage!
var articleTitle: String

// MARK: Public Init
init(articlePicture: UIImage, articleTitle: String) {
    self.articlePicture = articlePicture
    self.articleTitle = articleTitle
}

// Required NSCoding Protocol
required convenience init?(coder decoder: NSCoder) {
    guard let articlePicture = decoder.decodeObject(forKey: "articlePicture") as? UIImage,
        let articleTitle = decoder.decodeObject(forKey: "articleTitle") as? String
        else { return nil }

    self.init(
        articlePicture: articlePicture,
        articleTitle: articleTitle
    )
}

// Required NSCoding Protocal
func encodeWithCoder(coder: NSCoder) {
    coder.encode(self.articlePicture, forKey: "articlePicture")
    coder.encode(self.articleTitle, forKey: "articleTitle")
}

// Initialize [Search]
static var searches = [Search]()

static func getSearches() -> [Search]{
    return searches
}

static func setSearch(search: Search){
    searches.append(search)
}

// NSUserDefaults Searches Array funcs
static func saveSearches(){
    let searchData = NSKeyedArchiver.archivedData(withRootObject: searches)
    UserDefaults.standard.set(searchData, forKey: "searches")
}

static func loadSearches() -> [Search]{
    let searchData = UserDefaults.standard.object(forKey: "searches") as? NSData

    if let searchData = searchData {
        searches = (NSKeyedUnarchiver.unarchiveObject(with: searchData as Data) as? [Search])!
        return searches
    }
    return searches
}
}

Body:
In Swift 4 there is another way to encode/decode classes. Now you'll only have to conform to the protocol Codable. No more need to write all your encode and decodes and it supports classes without NSObject & enums & structs.

final class Search: Codable {

}

For more information, read https://developer.apple.com/documentation/swift/codable