Comments (7)
hi. not that i am aware of. due you have the stack trace? i will try to analyse.
from serialize.linq.
@esskar Here's an exemplar stack trace. The one client application is compiled, for example, with version 1.2.3.0 of the DTO assembly. The server, on the other hand is compiled with version 1.2.4.0 of the same. The DTO assembly is signed, but not sure if it makes any difference.
System.IO.FileLoadException: Could not load file or assembly 'MyDto, Version=1.2.3.0, Culture=neutral, PublicKeyToken=866519a7a698ba68' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'MyDto, Version=1.2.3.0, Culture=neutral, PublicKeyToken=866519a7a698ba68'
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.Type.GetType(String typeName)
at Serialize.Linq.ExpressionContext.<ResolveType>b__3(String n)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Serialize.Linq.ExpressionContext.ResolveType(TypeNode node)
at MyApp.Helpers.MyExpressionContext.ResolveType(TypeNode node) in e:\nb\MyApp\Helpers\MyExpressionContext.cs:line 19
at Serialize.Linq.Nodes.TypeNode.ToType(ExpressionContext context)
at Serialize.Linq.Nodes.MemberNode`1.ToMemberInfo(ExpressionContext context)
at Serialize.Linq.Nodes.MemberExpressionNode.ToExpression(ExpressionContext context)
at Serialize.Linq.Nodes.BinaryExpressionNode.ToExpression(ExpressionContext context)
at Serialize.Linq.Nodes.LambdaExpressionNode.ToExpression(ExpressionContext context)
at Serialize.Linq.Nodes.ExpressionNode.ConvertToExpression[TDelegate](ExpressionNode expressionNode, ExpressionContext context)
at Serialize.Linq.Nodes.ExpressionNode.ToExpression[TDelegate](Func`3 conversionFunction, ExpressionContext context)
at MyApp.DataService.QueryData(QueryRequest request) in e:\nb\MyApp\DataService.svc.cs:line 76
from serialize.linq.
Seems like this is what @esskar exactly tried to avoid, i.e. picking wrong types with the same names. I mean how can we assure without a complex introspection that your DTO lib actually contains compatible types?
from serialize.linq.
@vsoldatkin @esskar Using the sample code provided as part of Serialize.Linq for discussion, I think the answer to my question lies in how WcfContracts
is versioned. That is, if I need to makes changes to WcfContracts
, as long as the changes are backwards compatible, then I can maintain the same AssemblyVersion
number while bumping up the AssemblyFileVersion
number. That way, the WcfHost
(and WcfContracts
) can continue to evolve while leaving older clients behind until backwards compatibility is broken, in which case all older clients will have to upgrade.
But after studying this some more, I realized that the ultimate issue I am trying to solve is this: What if the client application had no knowledge nor access to WcfContracts
, but merely consumed my WCF service using its WSDL endpoint? In that case, how can Serialize.Linq be used?
I solved it by modifying the custom expression context subclass, like so:
public override Type ResolveType(TypeNode node)
{
var type = base.ResolveType(node);
if (type == typeof(PersonDto))
return typeof(Person);
if (type == null)
{
// Look at node.Name and make a guess based on string matching which class
// to map to, and ...
return thatType;
}
return type;
}
I figure this is no worse than the original version, which is hard-coding a mapping based on some knowledge about the classes.
I have implemented this and it is working for me.
from serialize.linq.
@bitaxis thanks for that!
idea: when the type to serialize is from an anonymous class, we use the full qualified name, otherwise we stick to type.Fullname
how does that sound?
from serialize.linq.
@esskar I think the way it is now is fine. What I ended up doing is implement two dictionaries I pre-populate. One is Dictionary<Type, Type>
, which I use to look up the type to return using the non-null return value of base.ResolveType()
as key. Otherwise, I use the second, which is Dictionary<Regex, Type>
, and I run node.Name
through all keys and taking the first match. It may not be foolproof, but a start.
Now, you could maybe clarify the purpose of ResolveType()
, as I stumbled across my solution by pure happenstance.
from serialize.linq.
Personally I don't like the idea of FullName based type guessing in any form. I'm pretty sure I'll be able to forge a test case to break it.
I would rather stick to the safe FQN-based implementation and provide an extension point for a user to implement his own unsafe ExpressionContext (specifically his own ResolveType implementation).
What if the client application had no knowledge nor access to WcfContracts, but merely consumed my WCF service using its WSDL endpoint? In that case, how can Serialize.Linq be used?
The only safe way is to share a DTO assembly. Otherwise it falls into a broader problem: What if I want to swap actual types for another types according to some rules, taking responsibility for all the risks?
And the answer is: Then implement your own ResolveType.
from serialize.linq.
Related Issues (20)
- bug when using expressions that contain dynamic HOT 1
- Question on LambdaExpression serialization HOT 1
- .net 5.0 problem HOT 2
- Serialize expression when it is a property of a class? HOT 2
- Cannot Serialize Expression Converted From Func HOT 3
- How to Revice Post arguments in core 3.1
- Change of License HOT 6
- Expression.Default not supported in serialization HOT 2
- Question about deserialization security: HOT 1
- Need your help with other issue HOT 2
- "System.InvalidOperationException: Sequence contains no matching element" during SerializeText HOT 1
- Known type cannot be an interface
- Error converting type: Bug or implementation issue - please help HOT 3
- Undefined variable error when using ToString in lambda expression HOT 2
- Deploy the latest build to NuGet HOT 3
- Serialize Linq Expression not working - Workaround / Suggestion HOT 2
- Target framework net standard 2.0 & 2.1 HOT 3
- Changes from 2.x to 3.x HOT 2
- Error when serializing an expression with nested method calls
- Method serialization issue
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from serialize.linq.