Returning an Interface from MVC Web API - asp.net-web-api

I have the following two classes
public interface INotification
{
int Id { get; set; }
bool IsNotificationShown { get; set; }
DateTime NotificationDate { get; set; }
}
public class Notification : INotification
{
public int Id
{
get;
set;
}
public bool IsNotificationShown
{
get;
set;
}
public DateTime NotificationDate
{
get;
set;
}
}
The WebAPI Controller has the following Action, I have hardcoded values for ease of read
public List<INotification> Get()
{
INotification notif = new Notification { Id = 1, IsNotificationShown = false, NotificationDate = DateTime.Now, NotificationDescription = "Desc", NotificationFrom = "Abcd", NotificationTo = "Abcd", NotificationTypeId = 1 } ;
return new List<INotification> { notif };
}
When I run this on the browser I get the following error
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
As soon as I change the return type from INotification to Notification then it works fine. Does anyone have any suggestions on how to fix this?

Just add the attribute KnowType to your class. Like this:
[KnownType(typeof(Notification))]
public class Notification : INotification
{
...

Related

Xamarin Picker Binding from nested classes

I am calling an API that returns nested classes (example below) and I am struggling to bind these to a Picker.
Is it possible to bind them nested classes to a picker as is? or do I need to somehow add them to a IList?
<Picker Title="Select a Currency" ItemsSource="{Binding CurrencyClass}" ItemDisplayBinding="{Binding currencyName}"/>
class MainPageViewModel : INotifyPropertyChanged
{
private Currencies _CurrencyClass;
public Currencies CurrencyClass
{
get { return _CurrencyClass; }
set
{
_CurrencyClass = value;
OnPropertyChanged();
}
}
}
This is a cut of the class they get desterilized too
public class Currencies
{
public class Rootobject
{
public Results results { get; set; }
}
public class Results
{
public XCD XCD { get; set; }
public EUR EUR { get; set; }
}
public class XCD
{
public string currencyName { get; set; }
public string currencySymbol { get; set; }
public string id { get; set; }
}
public class EUR
{
public string currencyName { get; set; }
public string currencySymbol { get; set; }
public string id { get; set; }
}
}
And this a cut of the json I am receiving.
{
"results": {
"XCD": {
"currencyName": "East Caribbean Dollar",
"currencySymbol": "$",
"id": "XCD"
},
"EUR": {
"currencyName": "Euro",
"currencySymbol": "€",
"id": "EUR"
}
}
}
So I figured out a work around for what I was aiming to achieve, this may not be a direct answer to my question but it is a solution for my issue.
I ended up just deserializing the JSON differently into a list of a Currency and then binding easily like you normally would.
class Currency
{
public string currencyName { get; set; }
public string currencySymbol { get; set; }
public string id { get; set; }
}
and how I deserialized it to fit in that class here, I parsed the JSON into a JObject and then for each child of each child I deserialize it into my Currency class.
List<Currency> cList = new List<Currency>();
HttpResponseMessage response = await client.GetAsync(urlAPI);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
JObject jo = JObject.Parse(responseBody);
var children = jo.SelectToken("results").Children();
foreach(var child in children)
{
var childrenOfChild = child.Children();
foreach(var c in childrenOfChild)
{
cList.Add(JsonConvert.DeserializeObject<Currency>(JsonConvert.SerializeObject(c)));
}
}

Xamarin MVVM Fill Model with a Model Property

How do work with a model with a model property inside of it?
I am pulling info from an api successfully but it does not work after I try to change my model from int to model like below:
public class TypeModel
{
[PrimaryKey]
public int pType { get; set; }
public DepartmentModel fDepartment { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Comments { get; set; }
public string Version { get; set; }
}
Here is the department model
public class DepartmentModel
{
public int pDepartment { get; set; }
public string Name { get; set; }
}
My ViewModel had this code and was working. Been trying to make changes as I think I need to change it in here somehow.
Types.Clear();
IEnumerable<TypesModel> types = await DataSource.GetTypesAsync(typeinfo.pType, true);
foreach (var column in types)
{
Types.Add(column);
}
Here is the deserialization from the api.
IEnumerable<TypeModel> TypeEnumerator;
public async Task<IEnumerable<TypeModel>> GetTypesAsync(bool r = false)
{
if (r)
{
var j = await HttpConstructor.GetStringAsync($"api/gettypes");
return await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<TypeModel>>(j));
}
return TypeEnumerator; ;
}
Here is the json information being produced from the api for types
{
"pType": 10,
"fDepartment": 1,
"title": "Bigwig",
"description": "For the bigwigs",
"comments": "high priority",
"version": "1.2.3"
},
{
"pType": 11,
"fDepartment": 1,
"title": "Frontdesk",
"description": "front end people",
"comments": "none",
"version": "1.2.4"
}
this is what I would do. There are undoubtedly other ways to approach it
public class TypeModel
{
[PrimaryKey]
public int pType { get; set; }
public int fDepartment { get; set; }
public DepartmentModel Department { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Comments { get; set; }
public string Version { get; set; }
}
List<TypesModel> types = await DataSource.GetTypesAsync(typeinfo.pType, true);
foreach (var type in types)
{
type.Department = new DepartmentModel
{
pDepartment = type.fDeparment,
Name = "???"
};
}
Got a solution going by using a Dictionary collection and avoided adjusting the model and mess up the business logic throughout the app.
I kept the original model and created a new one called TypesModel to use for list views.
public class TypesModel
{
[PrimaryKey]
public int pType { get; set; }
public Dictionary<int, string> fDepartment { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Comments { get; set; }
public string Version { get; set; }
}
Then I used Linq join to combine the information and also fill in the dictionary values.
var query = from t in types
join d in departments
on t.fDeparment equals d.pDepartment
select new TypesModel
{
pType = t.pType,
fDepartment = new Dictionary<int, string>()
{
{ d.pDepartment, d.Name }
},
Title = t.Title,
Description = t.Description
};

Object reference error in unit testing

i have a controller action
[HttpPost]
public ActionResult CreateFocus(FocusFormModel focus)
{
var errors = focusService.CanAddFocus(Mapper.Map<FocusFormModel, Focus>(focus)).ToList();
ModelState.AddModelErrors(errors);
if (ModelState.IsValid)
{
focusService.CreateFocus(Mapper.Map<FocusFormModel, Focus>(focus));
var createdfocus = focusService.GetFocus(focus.FocusName);
return RedirectToAction("Focus", new { id = createdfocus.FocusId });
}
return View("CreateFocus", focus);
}
This action is working fine but when i am writing unit test it is showing error
Object Reference Not set to an instance of an object
the uni test is
[Test]
public void Create_Focus()
{
// Arrange
GroupController controller = new GroupController(groupService);
// Act
FocusFormModel focus = new FocusFormModel();
focus.GroupId = 1;
focus.FocusName = "t";
focus.Description = "t";
Mapper.CreateMap<FocusFormModel, Focus>().ForAllMembers(opt => opt.Ignore());
Mapper.AssertConfigurationIsValid();
var result = (RedirectToRouteResult)controller.CreateFocus(focus);
Assert.AreEqual("Index", result.RouteValues["action"]);
}
My Model is described below
public class Focus
{
public int FocusId { get; set; }
[StringLength(50)]
public string FocusName { get; set; }
[StringLength(100)]
public string Description { get; set; }
public int GroupId { get; set; }
public virtual Group Group { get; set; }
public DateTime CreatedDate { get; set; }
public Focus()
{
CreatedDate = DateTime.Now;
}
}
and i am writing my view model as
public class FocusFormModel
{
public int FocusId { get; set; }
[Required(ErrorMessage = "*")]
[StringLength(50)]
public string FocusName { get; set; }
[Required(ErrorMessage = "*")]
[StringLength(100)]
public string Description { get; set; }
public int GroupId { get; set; }
public virtual Group Group { get; set; }
public DateTime CreatedDate { get; set; }
public FocusFormModel()
{
CreatedDate = DateTime.Now;
}
}
Can any one please help me
This line actually provides 2 chances to get null reference exception:
var errors = focusService.CanAddFocus(Mapper.Map<FocusFormModel, Focus>(focus)).ToList();
first of all focusService might be null
if focusService is not null then method call CanAddFocus(Mapper.Map<FocusFormModel, Focus>(focus)) might return null
That are just assumptions.
As Greg Smith said stack trace would be very helpful here.

How to keep the value of the source when using InjectFrom

By injecting values ​​into my domain object, I would keep the values ​​of some properties.
Example:
Domain model
public class Person
{
public string Name { get; set; }
public Guid ID { get; set; }
public DateTime CreateAt { get; set; }
public string Notes { get; set; }
public IList<string> Tags { get; set; }
}
View Model
public class PersonViewMode
{
public string Name { get; set; }
public Guid ID { get; set; }
public DateTime CreateAt { get; set; }
public string Notes { get; set; }
public IList<string> Tags { get; set; }
public PersonViewMode() { ID = Guid.NewGuid(); } //You should use this value when it is the Target
}
Sample
var p = new Person
{
ID = Guid.NewGuid() //Should be ignored!
,
Name = "Riderman"
,
CreateAt = DateTime.Now
,
Notes = "teste de nota"
,
Tags = new[] {"Tag1", "Tag2", "Tag3"}
};
var pvm = new PersonViewMode();
pvm.InjectFrom(p); //Should use the ID value generated in the class constructor PersonViewMode
if you delete the set; from from the ViewModel's ID then it won't be set;
otherwise you could save the value of ID in a separate variable and put it back after injecting,
or you can create a custom valueinjection that would ignore "ID" or would receive a list of properties to ignore as a parameter
here's the example for a custom injection that receives a list of property names to ignore:
public class MyInj : ConventionInjection
{
private readonly string[] ignores = new string[] { };
public MyInj(params string[] ignores)
{
this.ignores = ignores;
}
protected override bool Match(ConventionInfo c)
{
if (ignores.Contains(c.SourceProp.Name)) return false;
return c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type;
}
}
and use it like this:
pvm.InjectFrom(new MyInj("ID"), p);
if you need to ignore more, you can do like this:
pvm.InjectFrom(new MyInj("ID","Prop2","Prop3"), p);

Silverlight RIA request only returns 1

I have the following code...
internal sealed class Menu_Metadata
{
private Menu_Metadata() { }
[Key]
public int MenuHeaderID { get; set; }
public string MenuHeaderName { get; set; }
[Include]
[Association("MenuHeader_MenuItem", "MenuHeaderID", "MenuHeaderID")]
public IEnumerable<MenuItem> MenuItems { get; set; }
}
public class EmployeeMenuItem
{
[Key]
public int MenuItemID { get; set; }
public int MenuHeaderID { get; set; }
public string MenuItemName { get; set; }
}
[MetadataType(typeof(Menu_Metadata))]
public class EmployeeMenu
{
public int MenuHeaderID { get; set; }
public string MenuHeaderName { get; set; }
public IEnumerable<EmployeeMenuItem> MenuItems { get; set; }
}
[EnableClientAccess()]
public class EmployeeMenuService : DomainService
{
public IQueryable<EmployeeMenu> GetEmployeeMenu()
{
BusinessLogic.Employee blEmployee = new BusinessLogic.Employee();
int employeeId = blEmployee.GetEmployeeIdFromUserName(HttpContext.Current.User.Identity.Name);
var menuHeaders = blEmployee.GetEmployeeMenuHeaders(employeeId);
// This works here!
IQueryable<EmployeeMenu> retValue = from mh in menuHeaders
select new EmployeeMenu
{
MenuHeaderID = mh.ID,
MenuHeaderName = mh.HeaderName,
MenuItems = from mhi in mh.MenuHeaderItems
select new EmployeeMenuItem
{
MenuItemID = mhi.MenuItemID,
MenuHeaderID = mhi.MenuHeaderID,
MenuItemName = mhi.MenuItem.MenuItemName
}
};
return retValue;
}
}
which is consumed by a Silverlight Accordion control
EmployeeMenuContext employeeMenuContext = new EmployeeMenuContext();
accordion2.ItemsSource = employeeMenuContext.EmployeeMenus;
employeeMenuContext.Load(employeeMenuContext.GetEmployeeMenuQuery());
The MenuHeaderName's are coming through just fine, and the MenuItems is populated for the 1st MenuHeader, but the other 3 MenuItems are empty.
Any ideas why?
At what point is it easier to use EF4 and RIA??? This seems so incredibly and needlessly complex to get a simple Entity with a sub-class in it!
I'm not entirely sure, but it appears that the problem may have been that I was trying to databind in the xaml constructor. I created a Loaded event and moved the code there and it seems to work now.

Resources