I'm trying out RestSharp for a WP7 project. Having some trouble deserializing some XML with RestSharp. The object is null. Here's some of the relevant XML:
<?xml version="1.0" encoding="utf-8"?>
<api_response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<response_data>
<employee_information>
<employee>
<employee_sf_name>David</employee_sf_name>
<employee_first_name>Dave</employee_first_name>
<employee_last_name>Jones</employee_last_name>
</employee>
</employee_information>
</response_data>
</api_response>
And here's my request:
public static void executeRequest(Action<string> callback, string method)
{
var client = new RestClient();
var request = new RestRequest(Method.POST);
client.BaseUrl = App.url + method;
request.AddParameter("secret_key", Application.secret_key);
request.AddParameter("email", Application.email);
request.AddParameter("password", Application.password);
client.ExecuteAsync<Employee>(request, response =>
{
callback(response.Content); //prints the response as output
Debug.WriteLine("firstname " + response.Data.employee_first_name);
});
}
And here's the Employee object:
public class Employee
{
public Employee() { }
public int employee_id { get; set; }
public String employee_first_name { get; set; }
public String employee_last_name { get; set; }
}
Since the response comes back fine I tried deserializing it in a separate function, but without success:
public static void parse(string data)
{
Debug.WriteLine(data);
XmlDeserializer xml = new XmlDeserializer();
Employee employee = new Employee();
employee = xml.Deserialize<Employee>(new RestResponse() { Content = data });
Debug.WriteLine("last name " + employee.employee_last_name);
Debug.WriteLine("firstname " + employee.employee_first_name);
}
Thanks in advance if anyone can shed some light on the issue.
First off, the closing tag needs to be a closing tag. After I fixed that, I set up an enclosing class:
public class employee_information
{
public Employee employee { get; set; }
}
Then kept your original Employee class:
public class Employee
{
public Employee() { }
public int employee_id { get; set; }
public String employee_first_name { get; set; }
public String employee_last_name { get; set; }
}
Then, to deserialize it:
var empInfo = xml.Deserialize<employee_information>((new RestResponse() {Content = data}));
Adding request.RootElement = "employee"; should work with your existing code. If you don't want to start that far down the tree, you need to create classes that match the entire hierarchy.
Related
I want to update an entity in database. I use the aspnetboilerplate template project. I have a method UpdateAsset in the application layer:
public async Task UpdateAsset(UpdateAssetInput input)
{
var asset = ObjectMapper.Map<Asset>(input.Asset);
asset.Domain = asset.Domain.ToLowerInvariant();
// Update Twitter Id
var twitterName = input.Asset.SocialAccounts?.TwitterInfo?.Name;
if (twitterName != null)
{
var twitterId = await _twitterActivityManager.GetTwitterIdByTwitterName(twitterName);
if (twitterId != null)
{
input.Asset.SocialAccounts.TwitterInfo.Id = twitterId;
}
}
asset.SetData<SocialAccounts>(AssetExtensionData.SocialAccounts, input.Asset.SocialAccounts);
var connectedAsset = await _assetManager.GetAsset(input.Asset.LockedPositionInfo.ConnectedAssetId);
if (connectedAsset != null)
{
input.Asset.LockedPositionInfo.ConnectedAssetUnit = connectedAsset.Unit;
}
asset.SetData<LockedPositionInfo>(AssetExtensionData.LockedPositionInfo, input.Asset.LockedPositionInfo);
asset.SetData(AssetExtensionData.WithdrawalApiInfo, input.Asset.WithdrawalApiInfo);
await _assetManager.UpdateAsset(asset);
}
UpdateAssetInput:
public class UpdateAssetInput
{
public AssetDto Asset { get; set; }
}
AssetDto:
[AutoMap(typeof(Asset))]
public class AssetDto : AuditedEntityDto<string>
{
public const int SYMBOL_LENGTH = 10;
[Required]
[MaxLength(SYMBOL_LENGTH)]
public new string Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public string Website { get; set; }
[Required]
public string Domain { get; set; }
public string Logo { get; set; }
public string Organization { get; set; }
public string Unit { get; set; }
public SocialAccounts SocialAccounts { get; set; }
public LockedPositionInfo LockedPositionInfo { get; set; }
public WithdrawalApiInfo WithdrawalApiInfo { get; set; }
public decimal TotalAmount { get; set; }
public decimal Price { get; set; }
public bool IsDisable { get; set; } = false;
}
UpdateAsset in the AssetManager:
public async Task UpdateAsset(Asset asset)
{
try
{
await _assetRepository.UpdateAsync(asset);
}
catch (Exception e)
{
Logger.Error(e.Message, e);
throw new UserFriendlyException(L("AssetUpdateFailed"), asset.Name);
}
}
When I call the UpdateAsset of the application layer in front end, I get the exception:
System.InvalidOperationException: 'The instance of entity type 'Asset' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
So how to solve the problem ?
Normally, when we update a asset entity, we will do following 3 steps:
Get asset entity from db
set updated value to asset entity
Update asset entity
based on your error message, you may get asset entity from db twice
Get asset1 entity from db - tracked
Get asset2 entity from db - tracked
set updated value to asset2 entity
Update asset2 entity
Please check if you have above code snippet
Model:
[DataContract]
public class Employee
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[DataMember(Name ="id")]
public int Id{ get; set; }
[DataMember(Name = "fullName")]
public string FullName { get; set; }
}
[DataContract]
public class Department
{
public Department()
{
this.Employees = new List<Employee>();
}
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "employees")]
public List<Employee> Employees { get; set; }
}
Controller
public HttpResponseMessage Get([FromUri]Department model)
{
if (ModelState.IsValid)
{
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
Url : "http://localhost:2070/home/get/?id=1&name=IT&Employees=1,John"
I am trying to invoke above URL and the Model does not read the Employees. Other property like int,double,string,decimal are read by the Model.
Can anyone help me on what is the correct format in passing List thru Url.
Also, I dont want to decorate each of my class with modelbinders nor the parameter in my controller.
Tech : WebApi, .Net3.5
You need to specify the index of the list and property to bind with when using FromUri and list/array
Try it this way
http://localhost:2070/home/get/?id=1&name=IT&Employees[0].Id=1&Employees[0].Name=John
I am new to using SQLite.NET and the Extensions.
To my best ability I have followed the guides I've found but no records are being created in the many to many join tables and I've no idea why.
I have a solution NuGet dependency on the SQLiteNetExtensions project.
I have the following tables:
[Table("Contact")]
public class Contact
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[MaxLength(50)]
public string FirstName { get; set; }
[MaxLength(50)]
public string Surname { get; set; }
[ManyToMany(typeof(Participant))]
public List<Journey> Journeys { get; set; }
}
[Table("Journey")]
public class Journey
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[ManyToMany(typeof(Participant))]
public List<Contact> Contacts { get; set; }
[ManyToMany(typeof(Waypoint))]
public List<Location> Locations { get; set; }
}
[Table("Location")]
public class Location
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[MaxLength(50)]
public string Name { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
[ManyToMany(typeof(Waypoint))]
public List<Journey> Journeys{ get; set; }
}
public class Participant
{
[ForeignKey(typeof(Contact))]
public int ContactId { get; set; }
[ForeignKey(typeof(Journey))]
public int JourneyId { get; set; }
}
public class Waypoint
{
[ForeignKey(typeof(Location))]
public int LocationId { get; set; }
[ForeignKey(typeof(Journey))]
public int JourneyId { get; set; }
}
When I build the database I use the following test code:
string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "xandroid.db3");
var db = new SQLiteConnection(platform, dbPath);
db.DropTable<Location>();
db.DropTable<Waypoint>();
db.DropTable<Contact>();
db.DropTable<Participant>();
db.DropTable<Journey>();
db.CreateTable<Location>();
db.CreateTable<Waypoint>();
db.CreateTable<Contact>();
db.CreateTable<Participant>();
db.CreateTable<Journey>();
Location home = new Location { Name = "Home", Latitude=22.22, Longitude=22.22 };
Location perth = new Location { Name = "Perth", Latitude = 4444.4444, Longitude = 4444.4444 };
db.InsertAll(new List<Location> { home, perth });
Contact beans = new Contact { FirstName = "Beans", Surname = "Connor" };
Contact winston = new Contact { FirstName = "Winston", Surname = "Connor" };
db.InsertAll(new List<Contact> { beans, winston });
Journey travelToPerth = new Journey { Locations = new List<Location> { perth }, Contacts = new List<Contact> { beans, winston }};
Journey returnHome = new Journey { Locations = new List<Location> { home }, Contacts = new List<Contact> { beans, winston}};
db.InsertAll(new List<Journey> { travelToPerth, returnHome } );
When I access the data I use the following code:
var waypoints = db.Table<Waypoint>();
Console.Out.WriteLine(waypoints.Count() + " recorded waypoints");
var participants = db.Table<Participant>();
Console.Out.WriteLine(participants.Count() + " recorded participants");
var journeys = db.Table<Journey>();
Console.Out.WriteLine(journeys.Count() + " recorded journeys");
The output of which is:
0 recorded waypoints
0 recorded participants
2 recorded journeys
You are inserting the objects using plain sqlite.net methods, that know nothing about your relationships. To save and load relationships you have to use SQLite-Net Extension methods. Most sqlite-net methods also have a WithChildren alternative to save relationships:
import SQLiteNetExtensions.Extensions;
db.InsertAllWithChildren(new List<Journey> { travelToPerth, returnHome } );
Will insert both elements and insert the required records to Participant and Waypoint tables to save the relationships.
Note: This still requires Location and Contact elements to be already inserted in database. To insert objects recursively, take a look at the Cascade operations section of the SQLite-Net Extensions documentation.
I'm trying to create my profile type page for my simple blog site. I have two simple model class like this:
public class UserInfoModel
{
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
public class NewPost
{
public string PostTitle { get; set; }
public string PostStory { get; set; }
}
I have created a joint model class of user & post to pass to view like this:
public class UserPostModel
{
public UserInfoModel User { get; set; }
public NewPost Post { get; set; }
}
The methods I wrote to retrieve the user & post info are like this:
public int GetUserID(string _UserName)
{
using (var context = new TourBlogEntities1())
{
var UserID = from s in context.UserInfoes
where s.UserName == _UserName
select s.UserID;
return UserID.Single();
}
}
public UserInfo GetUserDetails(int _UserID)
{
using (var context = new TourBlogEntities1())
{
var UserDetails = (from s in context.UserInfoes
where s.UserID == _UserID
select s).Single();
return UserDetails;
}
}
public Post GetUserPosts(int _UserID)
{
using (var context = new TourBlogEntities1())
{
var entity = (from s in context.Posts
where s.UserID == _UserID
select s).Single();
return entity;
}
}
And finally I'm calling all my method from my controller action like this:
[Authorize]
public ActionResult MyProfile()
{
var Business = new Business();
var UserID=Business.GetUserID(User.Identity.Name);
var UserEntity=Business.GetUserDetails(UserID);
var PostEntity=Business.GetUserPosts(UserID);
var model = new UserPostModel();
model.User.UserName = UserEntity.UserName; // problem showing here
model.User.Email = UserEntity.Email;
model.Post.PostTitle = PostEntity.PostTitle;
model.Post.PostStory = PostEntity.PostStory;
return View("MyProfile",model);
}
A run time error showing like " object is not referenced to a object type or null object". I worked ok in a very similar way while passing single model. Whats I'm doing wrong here?
Modified your UserPostModel
public class UserPostModel
{
public UserPostModel()
{
User = new UserInfoModel();
Post = new Post();
}
public UserInfoModel User { get; set; }
public NewPost Post { get; set; }
}
NOTE: check each value before set to model it should not be null.
I have ObservableCollection with 3 columns: id, name, image.
First two are filed with data from db and I want to fill the last one with my data. In image column I would like to put some static part + id
Is it possible?
I assume that some for loop will do the job, but don't know where to start
EDIT - MY CODE:
Object:
public class HabitatDB
{
public int id { get; set; }
public string name { get; set; }
public string imagelink { get; set; }
}
Getting data:
ObservableCollection<HabitatDB> _habitatEntries = null;
private void GetHabitats()
{
string strSelect = "SELECT id, name FROM habitat ORDER BY id ASC";
_habitatEntries = (Application.Current as App).db.SelectObservableCollection<HabitatDB>(strSelect);
HabitatListBox.ItemsSource = _habitatEntries;
}
I lost almost whole day and by accident I found REALLY simple solution...
Just a small change in class and you don't need to mess with ObservableCollection AT ALL.
public class HabitatDB
{
public int id { get; set; }
public string name { get; set; }
public string imagelink { get { return string.Format("graphics/habitats/{0}.png", id); } }
}
Then just <Image Source="{Binding imagelink}"/>