Wix: Passing an object from one CustomAction method to another - Best Practice? - wix

I am interested in the best practice of the following scenario. I have a CustomAction method that hits a web service and returns some information that I use to populate a combo box. Later in the install process in another CustomAction method, I need to access some of the meta data returned from that first web service call.
In the first method, I create a List that is a public static member of my CustomAction class. In my second method when I access the list its empty.
My thoughts were to serialize it using xaml serialization into a session variable then deserialize it in my second method.
Am I way off here? Is there a better way?

I will assume that your second custom action is making configuration changes to the machine and running in the execute sequence as deferred with no impersonation. This means it can only access the CustomActionData property.
This means your first custom action will have to serialize the CustomActionData property for the second one to deserialize. Now the CustomActionData is a Key:Value collection and what you do with it ( including have a Key with a Value that is yet another serialized datatype ) is completely up to you.
Be sure to read the DTF documentation to understand how to use the CustomActionData type and members off the Session class to your advantage.

Related

Implementing a net-core Web API That Returns Previous Response

I'm currently building a Web API in net-core that has the following requirements:
All web transactions must have a unique Guid identifier for each endpoint
If an endpoint is hit with a previously used Guid, then the response that was given for this Guid is returned again
I was attempting to implement this by JsonSerializing the IActionResult inside the WebApi controller, but I ran into an issue where I can't deserialize all IActionResult responses since some don't have a constructor.
For example:
JsonSerializationException: Unable to find a constructor to use for type Microsoft.AspNetCore.Mvc.CreatedResult. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.
Does anybody know if it's possible to work around this?
Personally, I'd use the response caching middleware. You can make it vary on your GUID, so as long as that is included in the request, it will only render the action if the GUID is different.
Short of that, if you want to handle this manually, cache the JSON you're intending to return, not the full response object. Then, you do not need to re-query the database, etc., and you simply return the response, which is not all that much overhead.

JSON.NET JsonIgnore DeserializeObject

I created a Web API using VS 2012. I have a method with a custom object parameter that I am passing JSON to via Fiddler for testing:
[HttpPost, HttpPut]
public HttpResponseMessage UpsertProject(Projects p)
{
...
}
My Projects object has about a dozen properties marked as JsonIgnore. My assumption was that when my object was serialized into Json those properties would be ignored...which is true. However, when I debug my method I'm noticing that all the object properties marked with JsonIgnore are set to null even if the Json that I pass in from Fiddler is setting them. I also try to get data as Json and deserialize it into a new instance of the object but that also does not set the properties that are marked JsonIngore. I knew JsonIgnore would work for serializing but didn't think it would prevent properties from being set when deserializing. What's frustrating is I know that ScriptIgnore doesn't behave this way, but I want to use JSON.net to handle my serializing/deserializing. I've also created a windows app and tested the same serializing/deserializing functionality and it works in it. So I'm wondering if this is a Web API limitation with the JsonIgnore attribute?
If it works the way you want in the Windows application but not in the Web API, that tells me that the JSON serializer settings are different between the two. What settings are you using in the Windows app that makes it work? You can take those settings and apply them to the Web API serializer in the Register method of the WebApiConfig class (in the App_Start folder of your Web API project). For example:
JsonSerializerSettings jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.NullValueHandling = NullValueHandling.Ignore;
jsonSettings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
...
EDIT
OK, so if I understand you correctly, based on your most recent comments, you want everything to be deserialized if possible, but you only want two specific properties to be serialized and those apparently do not have null or default values. In that case, there are two approaches you can take:
Set the properties that you don't want serialized to null or zero or false (the default value) just before serializing. Because you have DefaultValueHandling set to Ignore, this will cause those properties not to be serialized.
Create several boolean ShouldSerializeXXX() methods in your class where XXX is the name of each property you don't want serialized. These methods should return false. See the first answer of this question for an example.
Don't use JsonIgnore because, as you have seen, this will cause the property to be completely ignored by Json.Net, both for serializing and deserializing.

Intercepting object creation in RavenDb

I am trying to run some code on objects that are loaded from RavenDB, and I need to do it just after the object has been loaded with its property values.
I've tried intercepting the deserialization process using a CustomCreationConverter and overriding ReadJson, but the object I can access at that point has all the properties set, except the one I need : the Id. Is there somewhere else I can slot into the pipeline in order to do this?
The reason you don't see the Id is because it's not part of the document, it's in the metadata as #id.
If you want to intercept client side, you can register a custom Conversion Listener. Create a class that implements IDocumentConversionListener and register it with documentStore.RegisterListener(). In the DocumentToEntity method, you can run your custom logic. The documentation is lacking on Listeners in general, but there is another topic that also uses them:
http://ravendb.net/kb/16/using-optimistic-concurrency-in-real-world-scenarios
The other option would be to add a bundle that intercepts on the server side. For that, you would use a Read Trigger.

StructureMap grouping of named instances

Long post - sorry....
I'm doing input validation for a WCF service and using StructureMap IoC to instantiate the appropriate validation objects.
I have 2 different validation groups:
Per object validation: means that one input parameter, will be resolve by the Ioc (e.g. Ioc.ResolveAll<IValidatorObject<InputParameter1>, .... <InputParameter2>... etc). If any rules are found, the validate method is invoked.
Per context validation: mean that validation rules are invoked, based on the current context (explicit roles). A context could be 'deposit money' or 'open bank account'. Context validation are usually dependent on 2 or more of the input parameters and is the key difference between object and context validation.
The input validation is performed in the BeforeCall event call in the IParameterInspector (provider/server side!). With this event I get a string containing the operation name (aka. the context) and an object[] with the input parameters.
The problem is that there's multiple validation rules for a single context and the only way I have figured out to register the context in the Ioc, is by using named intances. However I can only register 1 named instance pr. interface. And the interface is not uniquely identifiable by its signature. E.g.
Context rule for 'create account': IValidatorContext<User, Account>
Context rule for 'deposit money': IValidatorContext<User, Account>
So my question is, whether it is possible to register the context in StructureMap in any other way than named instances - or maybe a way to group named instances.
An alternative route, is to implement explicit interfaces for each context, so that the DepositMoney service method might look like this:
public Response Deposit(IDepositMoney inputArguements)
where IDepositMoney contains the input parameters.
So am I way off here, or can I somehow register a context in StructureMap? Or should I just go ahead and use explicit interface instead (3rd option?)
Thanks in advance
Ended up wrapping each set of input parameters in a context and used the context to register in StructureMap. Works like a charm!
The whole idea of named instances is that the name points to a single instance, so you won't be able to use that feature to do what you are trying to achieve. I would use explicit interfaces, since this will allow you to auto wire more things and have less calls to your container.

Will changing an Object signature break a WCF method call using that Object?

If I have an object that holds the parameters for my method. I need to change the Object to have an additional property. I have full control over the server, but not over all of the clients. Will this change make those clients break?
I am using a self-hosted service with a binary endpoint.
I am new to WCF so my apologies if this is a silly question.
I guess you are asking about a class that represents your DataContract.
Learn about DataContract versioning and how various changes in your DataContract affect the compatibility in MSDN
In short the answer is No, it will not break the client code. The serialized graph of the data contract will deserialize to the available data members matching by their names and assigned through the property setter method. Obviously in this case, your newly added data member will not have value. Since you have full control on the server side code, you just have to make sure this newly added member need to be dealt in such a way that it is meaningful in the new implementation and allow for default/unassigned value.