Coder Social home page Coder Social logo

odata's Introduction

maskx.OData

Introduction

maskx.OData support build a Odata database proxy turn your database into a OData WebApi server. Dynamic generate OData Controller from database.

With the web server build by maskx.odata, the client can do:

  • Query, insert, delete, update the database table
  • Query the view and table-valued function
  • Invoke the stored procedure

The Web API is followed the OData protocol (http://www.odata.org/)

Why this library

Quickstart

Setup WebApi

  class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOData();
            services.AddMvc();
        }
        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc(routeBuilder => {
                routeBuilder.MapDynamicODataServiceRoute("odata","db1",
                    new maskx.OData.Sql.SQL2012("odata", "Data Source=.;Initial Catalog=Group;Integrated Security=True"));
            });
        }
    }

Run or Deploy

  • Hit F5 to start the web server or deploy the project

Access the database by Web Api

Now you can access the database through the web API. you can visit this page for basic OData knowledge: http://www.odata.org/getting-started/understand-odata-in-6-steps/

Usage

Note

OData is case-sensitive, if you want case-insensitive, see Configuration

Requesting Entity Collections

  • Query Table
  $.get('db1/<table name>')
  .done(function (data) {alert(data.value) });
  • Query View
 $.get('db1/<view name>')
 .done(function (data) {alert(data.value) });
  • Query Table-valued function
 $.get('db1/<Table-valued function name>()')
 .done(function (data) {alert(data.value) });

Requesting an Individual Entity by ID

  $.get('db1/<table name>(<the value of ID>)')
  .done(function (data) {alert(data) });

Requesting an Individual Property

not support yet

Querying

you can user:

Data Modification

  • Create an Entity
  $.post('db1/<table>',{
    'col1':'col1 value',
    'col2':'col2 value',
    ...
  }).done(function (data) {alert(data.value) });
  • Update an Entity
  $.ajax({
    url:'db1/<table>(<ID>)',
    type:'PUT',
    data:{
      'col1':'col1 value',
      'col2':'col2 value',
      ...
    }
  }).done(function (data) {alert(data)});
  • Merge an Entity
$.ajax({
    url:'db1/<table>(<ID>)',
    type:'PATCH',
    data:{
      'col1':'col1 value',
      'col2':'col2 value',
      ...
    }
  }).done(function (data) {alert(data)});
  • Delete an Entity
  $.ajax({
    url:'db1/<table>(<ID>)',
    type:'DELETE'
  }).done(function (data) {alert(data) });

View

for view, only query is supported

$.get('db1/<view>').done(function (data) {alert(data.value) });

Stored procedure

 $.post('db1/<Stroed procedure name >()',{
    'par1':'par1 value',
    'par2':'par2 value',
    ...
  }).done(function (data) {alert(data) });

Table-valued function

$.get('db1/<table-valued function name>()')
.done(function (data) {alert(data.value) });
  • Parameter
   $.get('db1/<table-valued function name>(ParameterName1=arameterValue1,ParameterName2=ParameterValue2)')
   .done(function (data) {alert(data.value) });
  • Querying

you can query a table-valued function as a table

$.get('db1/<table-valued function name>()')
.done(function (data) {alert(data.value) });

Schema

the default schema of sql server is dbo, so you can query the table by name directly when the table's shcema is dbo

when the schema of a table is not dbo, you must query the table with schema name

$.get('db1/<schema name>.<table name>')
.done(function (data) {alert(data.value) });
  • Customer default schema

If you want make another schema( not dbo) as your default schema for the query url convenient, you can change it

public void Configure(IApplicationBuilder app)
{
  app.UseMvc(routeBuilder =>
  {
     var dataSource = new maskx.OData.Sql.SQL2012("odata", "Data Source=.;Initial Catalog=Group;Integrated Security=True");
     dataSource.Configuration.DefaultSchema = "schemaB";
     routeBuilder.MapDynamicODataServiceRoute("odata1", "db1", dataSource);
  });
}

Security

SQLDataSource has a BeforeExcute property, you can judge user's permission in there

new maskx.OData.Sql.SQL2012(<DataSourceName>)
{
   BeforeExcute = (ri) =>{
      if (ri.QueryOptions != null && ri.QueryOptions.SelectExpand != null) {

      }
      Console.WriteLine("BeforeExcute:{0}", ri.Target);
   }
 };

Audit

SQLDataSource has a BeforeExcute and AfterExcute properties, you can judge user's permission in there

SQL Server 2008

Handling special characters in odata queries

Special Character Special Meaning Hexadecimal Value
+ Indicates a space(space cannot be used in url) %28
/ Separates directories and subdirectories %2F
? Separates the actual URL and the Parameters %3F
% Specifiers special characters %25
# Indicates the bookmark %23
& Spearator between parameters specified the URL %26

Configuration

  • DefaultSchema :Defalut Schema name, default is dbo
  • LowerName: make the name of database object to lower, default is false

Contributing

Contributions are absolutely welcome!

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature Submit a pull request :D

License

The MIT License (MIT) - See file 'LICENSE' in this project

odata's People

Contributors

idemery avatar maskx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

odata's Issues

More than one relationship between two entities

Hello, I was having a look at your library and I think found an issue when a table has more than one column referencing the same foreign table.

For my experiment, since the nuget package didn't seem to work for net core, I cloned your repository and added a new ASP Net Core WebAPI project referencing the library.

I used World Wide Importers sample database from Microsoft.

Then, I configured the datasource for the Sales schema:

var ds = new maskx.OData.SQLSource.SQLServer("Sales", "Data Source=.;Initial Catalog=WideWorldImporters;User ID=sa;PWD=******");
ds.Configuration.DefaultSchema = "Sales";

Had to solve a missing assembly reference to Microsoft.SQLServer.Types by directly referencing said nuget package from my WebAPI project. Got a warning on run, but it started to serve content.

I asked for [webroot]/sales/Customers and the response got cut off in the middle of the 1st customer's JSON data, but it was returning a 200 OK status (!)

So I did a select for a property with [webroot]/sales/Customers?$select=CustomerName, which correctly returned the 663 rows.

I also noticed this exception being caught, but not thrown during first request execution:

Microsoft.OData.ODataException: A property with name 'Customers' on type 'Sales.Customers' has kind 'None', but it is expected to be of kind 'Navigation'.

Then I knew it must be a property on Customers which was causing all my woes.

I went to the metadata URL to inspect the type definition, and I found several properties with the same name:

                [...]
                <NavigationProperty Name="Customers" Type="Collection(Sales.Customers)" Partner="Customers">
                    <ReferentialConstraint Property="CustomerID" ReferencedProperty="BillToCustomerID" />
                </NavigationProperty>
                <NavigationProperty Name="Customers" Type="Collection(Sales.Customers)" Partner="Customers" />
                [...]
                <NavigationProperty Name="People" Type="Collection(Application.People)" Partner="Customers" />
                <NavigationProperty Name="People" Type="Collection(Application.People)" Partner="Customers" />
                [...]
                <NavigationProperty Name="Cities" Type="Collection(Application.Cities)" Partner="Customers" />
                <NavigationProperty Name="Cities" Type="Collection(Application.Cities)" Partner="Customers" />
                [...]
                <NavigationProperty Name="Invoices" Type="Collection(Sales.Invoices)" Partner="Customers">
                    <ReferentialConstraint Property="CustomerID" ReferencedProperty="CustomerID" />
                </NavigationProperty>
                <NavigationProperty Name="Invoices" Type="Collection(Sales.Invoices)" Partner="Customers">
                    <ReferentialConstraint Property="CustomerID" ReferencedProperty="BillToCustomerID" />
                </NavigationProperty>

As displayed, there are several navigation properties with the same name, some of them with the same definition, some not.

I checked the particular case of cities in the sample database, and as expected, there were two foreign keys from Customers to Cities (DeliveryCityID and PostalCityID).

On the other hand, I was only able to find a single foreign key on Customers referencing itself (BillToCustomerID).

I hope all this information might help you to identify and solve this limitation, because I think this library can get to be really useful if it can address most normal circumstances found in a database, and having several foreign keys linking two tables is not an uncommon one.

Filtering

I have a datasource where i only want to expose a subset of tables. Is there a way to set a filter on the odata service to accomplish this?

Exception when navingating to one of the odata uris

Hi!

I am trying to use the source code of your project in a new web api application. My web api starts fine, but when i navigate to one of the uris e.g. http://localhost/odata/db/activity i get the following exception:

Could you please assist?

System.InvalidOperationException occurred
HResult=0x80131509
Message=The container built by the container builder must not be null.
Source=System.Web.OData
StackTrace:
at System.Web.OData.Extensions.HttpConfigurationExtensions.GetODataRootContainer(HttpConfiguration configuration, String routeName)
at System.Web.OData.Extensions.HttpRequestMessageExtensions.GetRootContainer(HttpRequestMessage request, String routeName)
at System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateRequestScope(HttpRequestMessage request, String routeName)
at System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateRequestContainer(HttpRequestMessage request, String routeName)
at maskx.OData.DynamicODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection) in C:\Users<user>\Documents\Visual Studio 2017\Projects\odata.sqlserver\maskx.OData\DynamicODataPathRouteConstraint.cs:line 91
at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)
at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)

how can add swagger support?

how can add swagger support?

or any Reference Article?

BTW, the nuget pkg is not Latest version(it is net version,not support netcore), I clone the source code and add Reference to my project that it work!!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.