Manually Creating an OData feed in Asp.Net Core, Using feed in Power BI - asp.net-web-api

I am trying to manually write a Web Api that will serve as an OData feed. I don't need much functionality, just the ability to export data stored within Entity framework to an application such as Power BI. I only need to be able to view, so I was planning on just implementing GET requests.
I currently have a standard web api that returns back properly formatted JSON, but I am having trouble formatting this into something that I can import into Power BI as an OData Feed.
Here's a gist of what I have.
public class Report
{
public string ID { get; set; }
public string Name { get; set; }
public string UserID { get; set; }
...
}
[Route("api/[controller]")]
public class ReportController : Controller
{
...
[HttpGet("GetReports/{userID}")]
public IEnumerable<Report> GetReportsByUser(string userID)
{
return GetAllReportsByUser(userID);
}
...
}
I need something like this to work (obviously won't in the current form)

Since you are using ASP.NET Core 1 (aka ASP.NET 5), use the OData vNext package to build your OData service. There is a sample service on Github.

Related

Property marked with JsonIgnore is still shown in Swagger UI documentation for Web API

I'm using Swashbuckle package which integrates swagger with Web API project. I want to hide the property marked as Ignored in the documentation. I tried to use different ways such as IgnoreDataMember, DataContract & DataMember, JsonIgnore or XmlIgnore but nothing seems to work with swagger ui.
However, in default API documentation it works as expected. This is how my model looks like:
public partial class Model : BaseSettingsModel
{
public string ReceiptTitle { get; set; }
[IgnoreDataMember]
public FieldsEnum Fields { get; set; }
public string DisplayFields { get; set; }
}
Moving from version 1.3.0 to 1.3.6 will solve this for you. At least #JsonIgnore and #XmlTransient are being respected.
For JsonIgnore you need to pull in the JSON.net NuGet package.

Filtering queries across $expands with WebApi2 OData

I have a WebApi 2.1 OData (v 5.1.1) service backed in Entity Framework 6.1. I'm trying to lock it down from a security standpoint, so that users can only query data that is theirs. I have everything working fine, until you get to the $expands option.
For the sake of this discussion, consider the following simplified data model:
public class Scenario
{
public Guid Id { get; set; }
public Guid CreatedById { get; set; }
}
public class Property
{
public Guid Id { get; set }
public Guid CreatedById { get; set; }
public IQueryable<Scenario> Scenarios { get; set; }
}
When I call /Properties(guid'SOMEGUID')?$expand=Scenarios, I need to be able to make sure that only Scenarios where the CreatedById = CurrentUserId are returned. This needs to happen on the server-side and not in the client-side query.
WCF Data Services had QueryInterceptors that would handle this kind of situation... what is the equivalent in WebApi 2.1 OData?
Thanks!
here's a gist with a sample on how can you implement this on your own:
https://gist.github.com/anonymous/9237151
Based on my git, you can use a similar validator and implement your validation logic on a CanAcess method or similar. Let me know if this helps you.
We will have soon an official sample on http://aspnet.codeplex.com
There are two ways to solve your problem if I understood your question correctly.
Call the ApplyTo method of ODataQueryOptions on the IQueryable result
public IQueryable<Property> Get(ODataQueryOptions queryOptions)
{
....
return queryOptions.ApplyTo(properties);
}
Add attribute Queryable on the GetData method and let WebAPI handles the query option
[Queryable]
public IQueryable<Property> Get()
{
...
return properties;
}

Models - in Data Project or Web Project?

When creating a new ASP.NET MVC3 application, in the default project there is a Models folder. This Models folder includes the AccountModels - RegisterModel, LoginModel, etc.
I have a separate project for the DAL - it includes a repository and a service.
Now, I have a method in my service:
TblUser Register(RegisterModel model);
For this to work, I must reference the web project in my data project.
Is this appropriate, or should I include my Models folder in my data project instead?
Your first option is not appropriate. That's what's referred to as a circular dependency and it is bad.
Your second option is better, but still not great. Your model classes will undoubtedly have fields and methods which are applicable to your ui only. Those don't belong in your data layer any more than your data objects belong in your web tier. That's an example of coupling - also known as a poor separation of concerns - and it is also bad.
The best option is to separate out data which is needed by both tiers out into a distinct set of classes (sometimes referred to as dto's - data transfer objects - or poco's - plain old class objects). Those classes can reside in your data project or in a project entirely to themselves depending on your needs. If your service resides in a WCF service, these classes will typically be DataContracts. Then, within your MVC project you should have your models, as they are now, but they should contain references to your POCO's instead of holding any data of their own. So in your specific case you would create a RegistrationInfo class (or whatever you want to call it) in your data project, then add a field of type RegistrationInfo to your model and pass it to your service instead of the entire RegistrationModel.
EDIT: added an example
namespace MyProject.Data.Objects {
public class RegistrationInfo {
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Email { get; set; }
}
}
namespace MyProject.Data {
public class MyService {
public TblUser Register(RegistrationInfo info) {
// .. save to the database ..
}
}
}
namespace MyProject.UI.Models {
class RegistrationModel {
public RegistrationInfo Info { get; set; }
/* Fields which the ui needs but the database does not */
public bool ConfirmPassword { get; set; }
public bool AllowFreeEmailAddresses { get; set; }
public void Save() {
new MyProject.Data.MyService().Register(this.Info);
}
public RegistrationModel() {
this.Info = new RegistrationInfo();
}
}
}

Create custom login system with FormsAuthentication and more in ASP.NET MVC 3 Razor?

Sorry for the big title.
So I've been doing some research for making login systems. I've already made my own, but discovered a more secure way to do it.
As far as I know, the four basic components of this login system are:
FormsAuthentication
MembershipProvider
RoleProvider
Principal
I have this as my basic user model:
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string PictureUrl { get; set; }
public string Role { get; set; }
public string AccessToken { get; set; }
}
This is just for retaining the data from the database.
I still want to use this model with the components listed above.
Does anyone know a good and thorough tutorial that explains how to create a custom login system using the above components in MVC 3 Razor?
Thanks in advance.
You can build a custom 'login system' by implementing a custom version of MembershipProvider and RoleProvider that uses your own database. Then you can re-use all the rest of the built in authentication and authorization stuff.
MSDN has some details on how to build a MembershipProvider here and details on a custom RoleProvider here. Samples implementations are included.
You can use this open source project :
https://github.com/TroyGoode/MembershipStarterKit

Decorating serializable class with extra properties

I'm building a Windows Phone 7 application and I'm trying to decorate a generated class with an additional property to bind against, but I'm a bit puzzled on how to solve this architecturally. What I currently have is this class, which is generated with the xsd.exe tool from an XML file:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.Diagnostics.DebuggerStepThroughAttribute]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public class Session
{
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Abstract { get; set; }
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Speaker { get; set; }
[System.Xml.Serialization.XmlAttributeAttribute]
public string TimeslotBegin { get; set; }
[System.Xml.Serialization.XmlAttributeAttribute]
public string Location { get; set; }
[System.Xml.Serialization.XmlAttributeAttribute]
public string TimeslotEnd { get; set; }
[System.Xml.Serialization.XmlAttributeAttribute]
public string Title { get; set; }
}
I am fetching the XML from the web and deserializing this with a XmlSerializer, but I want to add an additional property to allow the user to "flag" items in the UI. I want to be able to bind to this property, so it should notify the UI thread when changed.
Any ideas on how to solve this?
For this situation, I'd recommend you separate your Model from your ViewModel.
The ViewModel is a data representation (including bindable properties) specifically designed for your UI.
The Model is the "pure" data representation, specifically designed for modelling your domain and for persistance (either directly to IsolatedStorage or perhaps persisted via a web service)
So, my recommendation is that you build some ViewModel classes for your UI to bind to - and then work out how these ViewModels interact with the Model.
As an aside, I'd also be cautious about using the XSD generated classes within Windows Phone 7 - WP7 seems to prefer the XDocument Linq XML classes, rather than the XmlDocument XML classes (but I may have this wrong!)

Resources