Odata-open Data Protocol is a standard for designing and using restful APIs. Rest itself is just a thought and idea for building Web services, and it does not provide a unified standard to limit how developers can design restful APIs. In fact, our actual development did not follow a unified standard to design WEBAPI. Because in most scenarios, it is not necessary to follow a unified standard. But in some scenarios, there is a standard that can bring great benefits.
The ideal for OData is that no matter which organization builds a restful API, as long as it complies with the OData standard. Other organizations can use this API to obtain/modify resources in the manner defined in the OData standard. This can be analogous to the SQL standard for RDBMS relationships. No matter what the relational database, if it claims to support the SQL standard, anyone can query the data using standard SQL query statements.
Another benefit of normalization: The OData protocol can be implemented into a common class library, and the use of this class library to create and access restful APIs can reduce the workload for developers.
First, create a new empty Webapi project
Second, add package Microsoft.AspNet.OData Package
1. Tools menu--nuget Package Manager--Package Manager console:
2. Enter Install-package Microsoft.AspNet.OData command
Third, add EntityFramework package (how to have data can use their own data source, skip directly)
1. Enter Install-package entityframework command
2. Create an Entity object
Setting up a database connection
public class Product
{
[Key] public
int ID {get; set;}
Public String Name {get; set;}
The [Ignoredatamember] property indicates that the
[Ignoredatamember] public
string Category {get; set;}
} is not visible in the EDM
Iii. Configuring the OData Endpoint
1. Open Webapiconfig Configuration EDM
private static Iedmmodel Generateedmmodel ()
{
var builder = new Odataconventionmodelbuilder
{
Namespace = "Odatamodel",
containername = "Defaultcontainer",
};
Builder. Entityset<product> ("Products");
Return builder. Getedmmodel ();
}
2. Add routes and set query parameters
public static void Register (httpconfiguration config)
{
//Web API configuration and Service
CONFIG. Mapodataserviceroute ("Productodata", NULL, Generateedmmodel ());
Set query parameter mode one
//config. Select (). (). Filter (). Expand (). Maxtop (100). Count ();
Set query parameter mode two
defaultquerysettings query = new Defaultquerysettings ()
{
Enablecount = true,
Enableexpand = True,
Enablefilter = True,
Enableorderby = True,
Enableselect = True,
maxtop = 100< c14/>};
Config. Setdefaultquerysettings (query);
}
Iv. Adding an OData controller
public class Odataapicontext:dbcontext
{public
odataapicontext (): Base ("odatadb")
{} public
dbset& Lt Product> products {get; set;}
Static Odataapicontext ()
{
//Closed database initialization operation
database.setinitializer<odataapicontext> (null);}
}
Database connection
public class Productscontroller:odatacontroller {private Odataapicontext db = new Odataapicontext ();
GET products//[queryable] [enablequery] public iqueryable<product> getproducts () {return db.
Products; }//GET products (5)//[queryable] [enablequery] public singleresult<product> GETPR Oduct ([Fromodatauri] int key) {return singleresult.create (db).
Products.where (Product = Product.id = = key)); }//<summary>//Update, modify///</summary>//<param name= "key" ></pa ram>//<param name= "Product" ></param>///<returns></returns>//PUT
Products (5) Public async task<ihttpactionresult> Put ([fromodatauri] int key, product product) { if (! Modelstate.isvalid) {return badrequest (MOdelstate);
} if (Key! = product.id) {return badrequest (); } db. Entry (product).
state = entitystate.modified; try {await db.
Savechangesasync (); } catch (Dbupdateconcurrencyexception) {if (!
Productexists (key)) {return NotFound ();
} else {throw;
}} return Updated (product); }///<summary>//New//</summary>/<param name= "Product" ></pa ram>//<returns></returns>//POST Products Public Async Task<ihttpactionresul T> Post (product product) {if (!
Modelstate.isvalid) {return badrequest (modelstate);
} Db.
Products.add (product); Await DB.
Savechangesasync ();
return Created (product); }//<summary>///</summary>/<param name= "key" ></param>
;
<param name= "Patch" ></param>///<returns></returns>//Patch products (5) [Acceptverbs ("PATCH", "MERGE")] public async task<ihttpactionresult> PATCH ([fromodatauri] int key, Delta <Product> patch) {if (!
Modelstate.isvalid) {return badrequest (modelstate); } Product Product = Await db.
Products.findasync (key);
if (product = null) {return NotFound (); } patch.
Patch (product); try {await db.
Savechangesasync ();
} catch (Dbupdateconcurrencyexception) { if (!
Productexists (key)) {return NotFound ();
} else {throw;
}} return Updated (product); }///<summary>//delete//</summary>//<param name= "key" ></param&
Gt <returns></returns>//DELETE Products (5) Public async task<ihttpactionresult> Delet E ([Fromodatauri] int key) {Product Product = await db.
Products.findasync (key);
if (product = null) {return NotFound (); } db.
Products.remove (product); Await DB.
Savechangesasync ();
Return StatusCode (httpstatuscode.nocontent);
} protected override void Dispose (bool disposing) {if (disposing) { Db.
Dispose (); } base.
Dispose (disposing); } private bool Productexists (int key) {return db.
Products.count (E = e.id = = key) > 0;
}
}
Run view
2. View $metadata
3. View Collections
V. Adding an OData client
1. Tools--Extensions and updates--install "OData v4 Client Code Generator"
2. Add a console program
3. Add New Item
4. Modify the Metadatadocumenturi path in the Odataclient.tt file
5. Save or right-click on the file to run the custom tool to generate the corresponding file
6. Implementation
Class program
{
static void Main (string[] args)
{
const string serviceuri = "http://localhost:57244/";
var container = new Defaultcontainer (new Uri (Serviceuri));
foreach (var p in container. Products)
{
Console.WriteLine ("{0} {1}", P.id, P.name);
}
Console.read ();
}
}