No XmlDocument and XDocument in VS2010 Express for Windows Phone - windows-phone-7

I use MS Studio 2010 Express for Windows Phone to build the app. In my app, I got the http respond and read it in string then I deserializer into the class object. It works fine in the class without List collection as a property. When it deserializer the class with List property, it got the error like this
Error in line 12 position 5. Expecting state 'Element'.. Encountered 'EndElement' with name 'ContactList', namespace 'http://schemas.datacontract.org/2004/07/DataObjects’.
I think I can read the xml and assign the value into the class. I searched to read xml file and a lot of website mentions to use XDocument .Prase method or xlmDocument.Load. However event adding the System.Xml.Ling as reference , I still cannot see XDocument .Parse method or xlmDocument . Would someone tell me what I should do in order to assign the following value into the class?
There is my class object:
public class CallDetails
{
public int id { get; set; }
public string summary { get; set; }
public string errorMsg { get; set; }
public int parentCallid { get; set; }
public string parentCallURL { get; set; }
public string assignedTo { get; set; }
public string OrgName { get; set; }
public DateTime onHoldSince { get; set; }
public DateTime onHoldUntil { get; set; }
public string requester { get; set; }
public bool isOnHold { get; set; }
private List<Contact> m_ContactList = new List<Contact>();
public List<Contact> ContactList
{
get { return m_ContactList; }
}
}
There is the respond:
<?xml version="1.0" encoding="utf-8"?><CallDetails xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/DataObjects">
<ContactList>
<Contact>
<Method>PriPhone</Method>
<Number>(604) 555-1234</Number>
</Contact>
<Contact>
<Method>Fax</Method>
<Number>(604)555-1234</Number>
</Contact>
</ContactList>
<errorMsg
i:nil="true" />
<id>0</id>
<isOnHold>false</isOnHold>
<onHoldSince>0001-01-01T00:00:00</onHoldSince>
<onHoldUntil>0001-01-01T00:00:00</onHoldUntil>
<parentCallURL>/Call/349551</parentCallURL>
<parentCallid>0</parentCallid>
<requester>Peter </requester>
<summary>Mobile Application Research</summary>
</CallDetails>

Just adding the reference to System.Xml.Linq won't do it, you also need to reference the namespace in the class header:
using System.Xml.Linq;
Then you can call something like XDocument doc = XDocument.Parse(content);. However, from what I can tell, you are trying to deserialize data, so you might want to use the XmlSerializer class instead for all the core work. You can find some code 'ispiration' here.

I found it that the CallDetail Class cause error. It should be like that
public List<Contact> ContactList { get; set; }

Related

"Not Found" Exception when trying to call UpdateAsync or InsertAsync

I'm creating a pretty basic Azure Mobile App based on the TodoItem example, and i'm running into a weird issue. I can connect to the table controller and call ToEnumerableAsync (GET) without issue, but as soon as I call UpdateAsync or InsertAsync, I get a 404 (Not Found) response. I tried recreating the table controller, disabling authentication etc. to no avail.
Log stream on Azure sees the PATCH message and returns the 404. Not terribly helpful...
my DTO looks like this:
public class Patient : EntityData
{
public string PersonalHealthNumber{ get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
}
and my client-side patient looks like this:
public class Patient
{
public string Id { get; set; }
public string PersonalHeathNumber { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
[Version]
public string Version { get; set; }
}
Try derive your client model from that TableData base class and remove the 2 properties Id and Version from your client model because they are in the base class

Serialize collection without root tag

I'm attempting to setup a Web API endpoint that has a specific requirement that the XML format be similar to this:
<broadcast>
<name></name>
<description></description>
<episode>
<title>&lt/title>
</episode>
<episode>
<title>&lt/title>
</episode>
...
</broadcast>
My models look like this:
[DataContract]
public class broadcast
{
[DataMember]
public string name { get; set; }
[DataMember]
public string description { get; set; }
[DataMember]
public List<episode> episodes { get; set; }
}
[DataContract]
public class episode
{
[DataMember]
public string title { get; set; }
}
The problem I'm running into is that the episode items get put into a container tag <episodes>. Is there any way to serialize the episodes list so that the container tag doesn't appear?
As it turns out there is a way to do this, but you must use the XmlSerializer. To do this add the following line to to your WebApiConfig.cs
config.Formatters.XmlFormatter.UseXmlSerializer = true;
Then add the [XmlElement] attribute to any collections you don't have to have a root tag. If you want to have a root tag use [XmlArray]. So in my example above:
[XmlType]
public class broadcast
{
[XmlElement]
public string name { get; set; }
[XmlElement]
public string description { get; set; }
[XmlElement] // could use [XmlArray] if I want a root tag
public List episodes { get; set; }
}
[XmlType]
public class episode
{
[XmlElement]
public string title { get; set; }
}
Kyle's answer is almost correct. You need [XmlElement("episode")] for this to work.
As far as I know removing the root element in a collection type is not possible. This is subject of Collection Type Serialization and even though there are multiple options to alter how collections are serialized using attributes like CollectionDataContractAttribute there isn't an option to remove the root for the Serialized collection element.
You can use MessageContract instead DataContract. Message contracts describe the structure of SOAP messages sent to and from a service and enable you to inspect and control most of the details in the SOAP header and body:
[MessageContract]
public class broadcast
{
[MessageBodyMember]
public string name { get; set; }
[MessageBodyMember]
public string description { get; set; }
[MessageBodyMember]
public List<episode> episodes { get; set; }
}
Here you can find more information and details --> https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-message-contracts

Parse.com - Adding <user>Pointer __User & ACL

I am attempting to add a row to a Class in my Parse database using the API
I have managed to get the row added but I noticed that both the 'ACL & user__user' fields are blank.
My Request class looks like this:
public class AccountDataRequest
{
public string OrderNo { get; set; }
public string SiteName { get; set; }
public string CreditDebit { get; set; }
public int Amount { get; set; }
public int CreditBalance { get; set; }
}
And my function looks like this:
public static AccountDataResponse AddTransaction(AccountDataRequest details)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.parse.com/1/classes/AccountData");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("X-Parse-Application-Id", "xxxxx");
httpWebRequest.Headers.Add("X-Parse-REST-API-Key", "xxxxx");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(details);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return JsonConvert.DeserializeObject<AccountDataResponse>(result);
}
}
}
The 'user__user' links to the 'objectID(String)' in mu Users class.
I have tried adding it to my class as a string but it throws and error.
Can anyone tell me how to get the ACL and 'user__user' populated please?
Thanks
UPDATE:
I have learnt that the Pointer is a structure so have amended my classes as follows:
public class AccountDataRequest
{
public string OrderNo { get; set; }
public string SiteName { get; set; }
public string CreditDebit { get; set; }
public double Amount { get; set; }
public int CreditBalance { get; set; }
public Pointer Pointer { get; set; }
}
public class Pointer
{
public string __type { get; set; }
public string className { get; set; }
public string objectId { get; set; }
}
So, when I now call the API with the following:
POST https://api.parse.com/1/classes/AccountData HTTP/1.1
Content-Type: application/json
X-Parse-Application-Id: xxxxx
X-Parse-REST-API-Key: xxxxx
Host: api.parse.com
Content-Length: 163
Expect: 100-continue
Connection: Keep-Alive
{"OrderNo":"9","SiteName":"Trev","CreditDebit":"Debit","Amount":1.0,"CreditBalance":999,"Pointer":{"__type":"Pointer","className":"AccountData","objectId":"fvJ8jPjyjx"}}
This call produces no errors and returns a createddate and an objectid but the user(Pointer <__User> is still null.
I also tried changing the className to "__User" to which the API responds:
{"code":111,"error":"invalid type for key Pointer, expected *AccountData, but got *_User"}
This is what the empty column looks like in my AccountData class
And I am trying to tie it to the objectId in my User table:
Can anyone see what is wrong please?
If the column in Parse is defined as a Pointer to _User, then you need to pass the appropriate structure to Parse and not just the objectId. Take a look at the Data Types section of the Parse REST SDK. It has a paragraph and sample for passing a Pointer structure through the API.
Similarly, for ACLs you need to specify that structure as well. Details for it are in the security docs for the SDK.
In both cases, if you want to use an object->JSON converter, you'll need to build an object that appropriately represents that structure. That'll be a bit easier for Pointers than ACLs as the former has predefined keys whereas the latter uses dynamic key names (e.g. objectIds and role names).
Updated to include class definition
public class AccountDataRequest
{
public string OrderNo { get; set; }
public string SiteName { get; set; }
public string CreditDebit { get; set; }
public double Amount { get; set; }
public int CreditBalance { get; set; }
public Pointer user { get; set; }
}

Problems with Model binding and validation attributes with asp.net Web API

I am writing a Web API with ASP.NET Web API, and make use of the following View Model.
I seem to be having a problem with the data binding when there are two validation attributes on a particular property (i.e. [Required] and [StringLength(10)]).
When posting a JSON value from a client to a controller action of the form:
// POST api/list
public void Post([FromBody] TaskViewModel taskVM)
I observe the following:
If I remove one of the multiple attributes everything is bound OK;
If I leave in the multiple attributes, the client recieves a 500 internal server error and the body of the Post method is never reached.
Any ideas why this happens?
Cheers
public class TaskViewModel
{
//Default Constructor
public TaskViewModel() { }
public static TaskViewModel MakeTaskViewModel(Task task)
{
return new TaskViewModel(task);
}
//Constructor
private TaskViewModel(Task task)
{
this.TaskId = task.TaskID;
this.Description = task.Description;
this.StartDate = task.StartDate;
this.Status = task.Status;
this.ListID = task.ListID;
}
public Guid TaskId { get; set; }
[Required]
[StringLength(10)]
public string Description { get; set; }
[Required]
[DataType(DataType.DateTime)]
public System.DateTime StartDate { get; set; }
[Required]
public string Status { get; set; }
public System.Guid ListID { get; set; }
}
You need to inspect what is inside in the 500 internal server
make sure that you turn customerror off in your web.config
If you selfhost web.API you need to set GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
use your browser development console's network tab (in IE, Chrome you can get the console with F12) or if you are using FireFox then use FireBug or a thrid party tool like Fiddler.
Then you can see what went wrong on the server and go further to solve your problem.
In your case this is in the response:
"Message":"An error has occurred.","ExceptionMessage":"Property
'StartDate' on type 'MvcApplication3.Controllers.TaskViewModel' is
invalid. Value-typed properties marked as [Required] must also be
marked with [DataMember(IsRequired=true)] to be recognized as
required. Consider attributing the declaring type with [DataContract]
and the property with
[DataMember(IsRequired=true)].","ExceptionType":"System.InvalidOperationException"
So your problem is not that you have two attributes but that you've marked your properties with [Required] to solve this the exception tells you what to do.
You need to add [DataMember(IsRequired=true)] to your required properties where the property type is a value type (e.g int, datatime, etc.):
So change your TaskViewModel to:
[DataContract]
public class TaskViewModel
{
//Default Constructor
public TaskViewModel() { }
[DataMember]
public Guid TaskId { get; set; }
[Required]
[DataMember]
[StringLength(10)]
public string Description { get; set; }
[Required]
[DataMember(IsRequired = true)]
[DataType(DataType.DateTime)]
public System.DateTime StartDate { get; set; }
[Required]
[DataMember]
public string Status { get; set; }
[DataMember]
public System.Guid ListID { get; set; }
}
Some side notes:
You need to reference the System.Runtime.Serialization dll in order to use the DataMemberAttribute
You need to mark your class with [DataContract] and you need to mark all of its properties with [DataMember] not just the required ones.

Json.Net JsonConvert not deserializing properly?

I'm using Json.Net to handle the deserialzing of the response of API calls from the Pipl.com API in my application, and it works fine but for some strange reason it won't deserialize a specific property of the JSON string that I feed to the JsonConvert.DeserializeObject method.
My class is this:
public class Source
{
public string Dsname { get; set; }
public bool IsSponsored { get; set; }
public string Url { get; set; }
public string Domain { get; set; }
public uint ExternalID { get; set; }
public Source()
{
}
}
and everything except the Dsname gets deserialized properly. The Json to be converted is like this:
"source": {
"#is_sponsored": false,
"#ds_name": "Personal Web Space -MySpace",
"url": "http://www.foo.bar"
"domain": "myspace.com"
}
Any idea how to go about this problem? Thank you in advance.
I added a wrapper class and specified the property name as attributes, like this:
public class Source
{
[JsonProperty(PropertyName = "#ds_name")]
public string Dsname { get; set; }
[JsonProperty(PropertyName = "#is_sponsored")]
public bool IsSponsored { get; set; }
public string Url { get; set; }
public string Domain { get; set; }
public uint ExternalID { get; set; }
}
public class RootObject
{
public Source source { get; set; }
}
Then I was able to deserialize fine:
var json = "{\"source\": { \"#is_sponsored\": true, \"#ds_name\": \"Personal Web Space -MySpace\", \"url\": \"http://www.foo.bar\", \"domain\": \"myspace.com\"}}";
var des = JsonConvert.DeserializeObject<RootObject>(json);
Note that I:
- wrapped your sample in a curly braces to make it valid JSON
- added a missing comma
- changed the value of "#is_sponsored" to not be the default value to verify it is desearialized correctly.
Ok I realize, this is a pretty old thread. But I ran into a similar issue earlier and came across this thread.
In my case the class I was trying to se/deserialize had a List<ClassName> public property in it. Which serialized fine, but wont deserialize. I switched it to ClassName[] and the fixed the deserialization problem.
Hope it helps someone else who comes across this thread, or at least gives them something else to look for.

Resources