HttpContext.Current cannot be serialized - c#

I have a line
string serializedContext = JsonConvert.SerializeObject(HttpContext.Current)
but I am getting exception on this line.
Self referencing loop detected for property 'Context' with type 'System.Web.HttpContext'. Path 'ApplicationInstance'.
I am trying to pass serailized context to web service.
Why that self-referencing loop is detected and what could be the way out?

The Misconception:
Serializing your context and de-serialize it on the other side makes no semantical sense: if you send it to a remote web service, it will have its own http context.
Working around the problem
Instead, what you might want to do is : create a new object with just the data you need to use on the remote web service.
Don't consider it as being a context, think of it as a data transfer object that contains all the things you need to get the job done on the other side.
Additional considerations
You might think it is painful to basically create a new object that contains the same data as your HttpContext, but you can mitigate the tediousness of copying the values from one object to the other by using AutoMapper in order to copy the values from one object to the other without the need to write the code yourself (it is convention-based).
Hope this helps.

You can try :
string serializedContext = JsonConvert.SerializeObject(HttpContext.Current, Formatting.Indented,
new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

Related

c# SOAP with service reference is not showing real response

I'm creating an UWP app, that needs to connect to asmx service. I've done that by using service reference, which works with TempConvert but not with my asmx service
This is how my code looks like
HelpdeskSoapClient HPsoapClient = new HelpdeskSoapClient();
getIncInput input = new getIncInput();
input.username = "450";
getIncResponse realresponse;
realresponse= await HPsoapClient.getIncAsync(input);
Debug.Write(realresponse);
but response is not an XML file or something else, but "DTS.helpdesk.getIncResponse"
Any clues ?
getIncResponse is the object that is returned by the service when you make the call.
When you pass realResponse into the Debug.Write, since it's an object, the base functionality of ToString() is called, which unless overridden in the object will return the fully qualified type name - i.e., DTS.helpdesk.getIncResponse.
You should be able to access the properties of the object to get the data, similar to how you set the username on the getIncInput object (input.username = "450";).
The temperature conversion service worked because it returns a simple type (string), not a complex type (getIncResponse). There is no error here.

Why the result from the web service references and Service references are different?

I am bit curious about one thing which has happen while trying to understand the concept of Service References and Web Service References.
What I did is?
In my project I have added a web service as a Service Reference and trying to get my script run through the use of client.
But while getting result it is throwing an exception as in the following image:
I have tried to trace out the cause but not able to get the proper answer for that.
I have following code for the resultant object.
[
ComVisible(false),
Serializable,
SoapTypeAttribute("RecordList", "http://www.someadd.com/dev/ns/SOF/2.0"),
XmlType(TypeName="RecordList", Namespace="http://www.someadd.com/dev/ns/SOF/2.0")
]
public class MyRecordListWrapper
{
private IxRecordList recordList = null;
private const string XMLW3CSchema = "http://www.w3.org/2001/XMLSchema";
[SoapElement("Headers")]
public Header[] Headers = null;
[SoapElement("Records")]
public Record[] Records = null;
// some methods to work on intialization
public SmRecordListWrapper(ref IxRecordList p_RecordList)
{
recordList = p_RecordList;// record list initialization
Headers = CreateWrapperHeaders(); // will return header class object
Records = CreateWrapperRecords(); // will return record object
}
}
Can anyone tell me why this error is showing for me?
While adding reference as a Web Service Reference
when I add the same reference as a web reference that time the program is not showing any error and runs successfully?
So can anyone tell me what is the difference in working with the same code using service reference and web service reference?
and Which is a correct way to ass references?
Hope I will get some more described answers to make the things easy to understand.
Thanks in advance.
Adding a web reference, visual studio uses xsd.exe to generate the classes from the service metadata. This uses XmlSerializer under the hood.
Adding a service reference, visual studio uses svcutil.exe to generate the classes from the metadata. This uses DataContractSerializer under the hood.
Two separate tools, two outcomes. For general information, DataContractSerializer is a lot less forgiving when it comes to generating classes from metadata.

How can I have a persistent data through different Context in a webservice?

So we have a webservice that is called from different applications and it runs an extraction of data which takes a while and we don't want it to run multiple times. So we thought we could set an HttpContext.Current.Application["isRunning"] to be persistent through all the requests like :
if ((bool)HttpContext.Current.Application["isRunning"])
And it doesn't work, since a new HttpContext is created when an other application call the webmethod.
Except writing onto the disk or in AppSettings I don't see how I can persist data through every request to only have one instance of my webmethod running at a time. I've tried with Application, Cache and static variables but they all do not persist across requests. It seems it creates a new instance each time.
Preventing a new instance to be created or persist data through instances would fix the issue. Any hint?
You could use EnterpriseLibraries Caching Block to cache the data following extraction.
http://www.codeproject.com/KB/web-cache/CachingApplicationBlock.aspx
Once you have the Enterprise Library assemblies referenced, it's just a case of adding a few lines to your web.config and then using code such as the following inside your service.
//Create Instance of CacheManager
ICacheManager _objCacheManager = CacheFactory.GetCacheManager();
AbsoluteTime timeToExpire = new AbsoluteTime(TimeSpan.FromMinutes(60));
MyData myData = null;
myData = (MyData)cacheManager.GetData("ref");
if (myData == null)
{
//get the data
cacheManager.Add("ref", myData, CacheItemPriority.Normal, null, timeToExpire);
}
return myData;
Take a look at the following links, which provide useful information on wanting to use the Singleton pattern with web services.
http://forums.asp.net/t/881617.aspx/1
http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/72274741-dbbe-4a64-a360-6bbe60026ec9/
http://msdn.microsoft.com/en-us/library/ff650316.aspx

Unable to cast object of type MyObject to type MyObject

I have this scenario where a webservice method I'm consuming in C# returns a Business object, when calling the webservice method with the following code I get the exception "Unable to cast object of type ContactInfo to type ContactInfo" in the reference.cs class of the web reference
Code:
ContactInfo contactInfo = new ContactInfo();
Contact contact = new Contact();
contactInfo = contact.Load(this.ContactID.Value);
Any help would be much appreciated.
This is because one of the ContactInfo objects is a web service proxy, and is in a different namespace.
It's a known problem with asmx-style web services. In the past I've implemented automatic shallow-copy to work around it (here's how, although if I were doing it again I'd probably look at AutoMapper instead).
For example, if you have an assembly with the following class:
MyProject.ContactInfo
and you return an instance of it from a web method:
public class DoSomethingService : System.Web.Services.WebService
{
public MyProject.ContactInfo GetContactInfo(int id)
{
// Code here...
}
}
Then when you add the web reference to your client project, you actually get this:
MyClientProject.DoSomethingService.ContactInfo
This means that if, in your client application, you call the web service to get a ContactInfo, you have this situation:
namespace MyClientProject
{
public class MyClientClass
{
public void AskWebServiceForContactInfo()
{
using (var service = new DoSomethingService())
{
MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1);
// ERROR: You can't cast this:
MyProject.ContactInfo localContactInfo = contactInfo;
}
}
}
}
It's on that last line that I use my ShallowCopy class:
namespace MyClientProject
{
public class MyClientClass
{
public void AskWebServiceForContactInfo()
{
using (var service = new DoSomethingService())
{
MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1);
// We actually get a new object here, of the correct namespace
MyProject.ContactInfo localContactInfo = ShallowCopy.Copy<MyClientProject.DoSomethingService.ContactInfo, MyProject.ContactInfo>(contactInfo);
}
}
}
}
NOTE
This only works because the proxy class and the "real" class have exactly the same properties (one is generated from the other by Visual Studio).
As several of the other answers have suggested, it is because .NET sees them as two different classes. I personally would recommend using something like AutoMapper. I've been using it, and it seems pretty awesome. You can copy your objects in 1-2 lines of code.
Mapper.CreateMap<SourceClass, DestinationClass>();
destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance);
Actually this is not a bug. It's a problem with the version changes of your own project!
Because your final run don't use the original imported references on compile!
For example, I was making a chat server, client. I used a packet structure to transmit data on client project.
Then imported the same reference to server project.
When casting Packet packet = (Packet)binaryFormatter.Deserialize(stream); I got the same error. Because the actual running reference at server project is not the reference now at client project! Because I have rebuilt client project many times after!
In casting <new object>=(<new object>) <old object> always the new object needs to be a newer or same version as the old object!
So what I did was I built a separate project to create a DLL for the Packet class and imported the DLL file to both projects.
If I did any change to Packet class, I have to import the reference to both client and server again.
Then the casting won't give the above exception!
How are you referencing the class in your web service project as well as consumer project? If you have simply used a file link, this could well explain the cause of the error. The way serialiasation works for .NET (Web Services or otherwise I believe) is by using reflection to load/dump the data of an object. If the files are simply linked, then they are actually getting compiled to different types in different assemblies, which would explain why you have the same name but can't cast between them. I recommend creating a 'Core' library which both the web service and consumer project references, and contains the ContactInfo class which you use everywhere.
This isn't a problem - it's a feature.
They are two independent classes. Compare the two, and notice that the proxy class has none of the constructors, methods, indexers, or other behavior from the original class. This is exactly the same thing that would happen if you consumed the ASMX service with a Java program.
Seems like you have two different classes on both ends. Your application has ContactInfo class and your webservice also have the ContactInfo class. Both are two completely different classes. One way is to use the WebService class on your side. If you are using ContactInfo inside your web service then it will be serialized and will be available on the client side for use.
You can also modify your References.cs file generated by Visual Studio when the web reference is added. If you remove the proxy generated classes and add a reference (using statements) to your personal classes, you'll be able to use them straight away, without shallow copy / reflection or heavy mapping. (but you'll have to re-apply your modification if you regenerate the proxy layer).
I also tried to serialize the proxy object and deserialize them back in my DTO classes but it was quite heavy resources wise so I ended up modifying the References cs generated layer.
Hope it will help other people coming here :)
Kindly.

Passing a custom object to a Windows Workflow WCF Service

I'm having a problem passing an object for some reason and I'm not sure why. I'm getting a Object reference not set to an instance of an object error.
Essentially from my client application I make a call to a Windows Work...
Client Code
Workflow1Client client = new Workflow1Client();
ACME.Order newOrder = new ACME.Order();
newOrder.Property1 = "xyz";
//set all the other properties
string status = client.GetData(newOrder);
//**This is where object reference error occurs**
Proxy Expecting
public string GetData(ACME.Order NewOrder)
{
return base.Channel.GetData(NewOrder);
}
Workflow Code
[ServiceContract]
public interface IWorkflow1
{
[OperationContract]
string GetData(ACME.Order NewOrder);
// TODO: Add your service operations here
}
I'd appreciate any help on this. Also beyond this question is sending a Object (ACME.Order) good practice or should I be trying to tackle this a different way?
Thanks
I have run into this myself and in my case it was a Serialization error on the custom object. To be able to send a custom object across WCF it should have the [Serializable] attribute. To test, see if you can serialize the object to an XML file. If that fails the WCF transfer will not work.
Hope that helps.

Categories

Resources