您的位置:首页 > 编程语言 > ASP

Consuming ASP.NET WEB API using ASP.NET MVC4 and RestSharp

2015-03-16 02:21 1076 查看
原文:http://www.codeproject.com/Articles/826359/Consuming-ASP-NET-WEB-API-using-ASP-NET-MVC-and-Re

相关文档:RestSharp====> https://github.com/restsharp/RestSharp/wiki

RestSharp用法小结:http://www.cnblogs.com/Mainz/p/3531243.html

使用RestSharp库消费Restful Service:http://www.cnblogs.com/shanyou/archive/2012/01/27/RestSharp.html




Contents

Introduction
Background
Pre-requisite
Why
RestSharp?
What
are we going to consume?
Create
the Web Project
Add
RestSharpsupport to project
Add
Rest client
Create
ModelClass
Describing
modelclass
Why
all checks are at client side?
Create
controller
Describing
controller
Create
view
Executing
the project
Points
of Interest


Introduction

In most scenarios, we develop an application of ASP.NET MVC4 using ASP.NET WEB API. But as a RESTFul service like ASP.NET WEB API, we meant to use by different clients. In this article, we will see how to consume simple ASP.NET WEB API using ASP.NET MVC4 (as
a client) with RestSharp(simple Rest and HTTP client for .NET).


Background

Before going through this article, I recommend you read my earlier article,
where I defined how to create an ASP.NET WEB API (Crud Operations using Fluent NHibernate).


Pre-requisite

To implement and play with the source code, one should have:

Visual Studio 2013 express or later
ASP.NET MVC4 or later
ASP.NET WEB API2 or later
Basic knowledge of RestFul Services
Basic knowledge of ASP.NET WEB API
Basic knowledge of ASP.NET MVC4 or later


Why RestSharp?

As we are going to use RestSharpto call our ASP.NET WEB API URIs, so, first of all, let's discuss
"RestSharp"
. This
is nothing but a Simple REST and HTTP API Client for .NET. It provides us with a simple way by which we can just initialize a
RestClient
,
pass a
Request
, define a
Method
 (GET, POST, PUT, DELETE)
and get a
response
.

Following are commonly used snippets:

Hide Copy Code
//Create a restclient
RestClientrestClient = new RestClient("url");

//Create request with GET
var request = new RestRequest("api/serverdata", Method.GET);


Do not forget to provide
RequestFormat
and
RestSharp
automatically
serialize/deserialize complex objects like Models like
ServerDataModel
in our demo project.

Hide Copy Code
//Do not forget while using complex types
var request = new RestRequest("api/serverdata", Method.GET)
 {RequestFormat = DataFormat.Json};


Get formatted result for complex types:

Hide Copy Code
var response = restClient.Execute<List<ServerDataModel>>(request);


There are many more features that we are not covering in this article. Please refer to RestSharpWiki.


What Are We Going to Consume?

As mentioned earlier, in this article, we will consume an existing ASP.NET WEB API URIs (hosted on server), below is the table mentioning all URIs:
[thead]
[/thead]

ActionHTTP methodRelative URI
Get a list of serverdata
GET
/api/serverdata
Get a serverdata by ID
GET
/api/serverdata/id
Get serverdata by datatype
GET
/api/serverdata/type/datatype
Get serverdata by machine IP
GET
/api/serverdata/ip/ip
Create a fresh serverdata
POST
/api/serverdata
Update an existing serverdata
PUT
/api/serverdata/id
Delete an existing serverdata
DELETE
/api/serverdata/id
Refer to the demo app: Demo ASP.NET WEB API.


Create the Web Project

Let's start creation of our new ASP.NET project (client project) by following the below mentioned step(s):

Start Visual Studio and select File->New->Project (or enter Ctrl + Shift + N).



In the Templates dialog, select Installed Templates and then expand the Visual C# node.
Under Visual C#, select Web. In the list of project templates, select ASP.NET MVC4 Web Application, name the project and click 'ok'.

I named my project as
consumewebapi
, you can choose whatever you want.


From Project Template, select Internet Application and Razor from View
Engine dropdown list and click 'ok'.



You can also check Create unit test project checkbox, if are doing Test driven development and I highly recommend the same. In this article, we
are not covering this part.

Now, after the above step(s), we have default ASP.NET MVC4 project template with us, later on we will add our stuff.




Add RestSharpSupport to Project

We are going to use
RestSharp
to consume our ASP.NET WEB API, follow these steps:

Goto Tools->NuGet Package Manager->Package Manager Console.

From Package Manager Console, run the following command:

Hide Copy Code
Install-Package RestSharp




It will install RestSharpcurrent version for your project
consumewebapi
.


Add Rest Client

From Solution Explorer, create a new folder and named it Helper - this folder will contain all our helper
classes required for RestSharpclient (these classes will play an interface between our client and services).
Add an interface and name it
IServerDataRestClient
.
Complete code of
IServerDataRestClient
looks like:

Hide Copy Code
public interface IServerDataRestClient
{
    void Add(ServerDataModelserverDataModel);
    void Delete(int id);
    IEnumerable<serverdatamodel> GetAll();
    ServerDataModelGetById(int id);
    ServerDataModelGetByIP(int ip);
    ServerDataModelGetByType(int type);
    void Update(ServerDataModelserverDataModel);
}


Add new class under Helper folder and named it as
ServerDataRestClient
and
implement interface
IServerDataRestClient
:

Hide Copy Code
public class ServerDataRestClient: IServerDataRestClient
{
 //implementation
}


We need to create a
RestClient
, create a variable
private
 readonly RestClient_client;
in the class and initialize the same in the constructor.

Hide Copy Code
//initializing RestClient
public ServerDataRestClient()
{
 _client = new RestClient(_url);
}


In the above, while we are initializing
RestClient
object, we are providing
BaseUrl
nothing
just a complete name of url like http://myexample.com/.

We can also do this:

Hide Copy Code
 _client = new RestClient{BaseUrl= _url};


We are fetching base URL from our config files, why it is in config files. It is recommended for large projects where we have different environments
like Dev, Staging,QA, Prod, etc.

Hide Copy Code
//getting base url from config
private readonly string _url = ConfigurationManager.AppSettings["webapibaseurl"];


Now, we required a request it is nothing but contains a resource and a method.



By providing
{RequestFormat = DataFormat.Json};
we are telling
RestClient
to
provide us an output in the form of Json. This is required while you are working with complex classes, like here we are using
ServerDataModel
class.

In DEBUG mode, check
_client
in Quick watch (Ctrl + D,Q), you will find all the things we set while creating our
RestClient
object.



Our client is ready to convey our request and get the response.

Hide Copy Code
var response = _client.Execute<List<ServerDataModel>>(request);


The above will give us the output in a list of our
ServerDataModel
class.

Open Quick watch for
response
, you will get two nodes
[RestSharp.RestResponse<System.Collections.Generic.List<ConsumeWebAPI.Models.ServerDataModel>>]
 {RestSharp.RestResponse<System.Collections.Generic.List<ConsumeWebAPI.Models.ServerDataModel>>} RestSharp.RestResponse<System.Collections.Generic.List<ConsumeWebAPI.Models.ServerDataModel>>
and
Data.




First node contains our actual content in JSON format with other information, e.g.,
ContentLength
,
ContentType
,
Cookies
,
ErrorMessage
,
Header
,
Request
,
ResponseStatus
,
StatusCode
,
etc.

Data, node contains our formatted data as we requested and required. In our case, it is a list of type
ServerDataModel
.
We will use this modeland our view will show later.

We can also request for a specific resource like if we need record by id, then we can do:

Hide Copy Code
var request = new RestRequest("api/serverdata/{id}", Method.GET) {RequestFormat = DataFormat.Json};

request.AddParameter("id", id, ParameterType.UrlSegment);


Below will give us output of type
ServerDataModel:


Hide Copy Code
var response = _client.Execute<serverdatamodel>(request);


Here, is our complete
ServerDataRestClient
helper class:

Hide Shrink

Copy Code
public class ServerDataRestClient: IServerDataRestClient
{
private readonly RestClient_client;
private readonly string _url = ConfigurationManager.AppSettings["webapibaseurl"];

public ServerDataRestClient()
{
_client = new RestClient{BaseUrl= _url};
}

public IEnumerable<serverdatamodel> GetAll()
{
var request = new RestRequest("api/serverdata", Method.GET) {RequestFormat = DataFormat.Json};

var response = _client.Execute<list<serverdatamodel>>(request);

if (response.Data == null)
throw new Exception(response.ErrorMessage);

return response.Data;
}

public ServerDataModelGetById(int id)
{
var request = new RestRequest("api/serverdata/{id}", Method.GET) {RequestFormat = DataFormat.Json};

request.AddParameter("id", id, ParameterType.UrlSegment);

var response = _client.Execute<serverdatamodel>(request);

if (response.Data == null)
throw new Exception(response.ErrorMessage);

return response.Data;
}

public ServerDataModelGetByType(int type)
{
var request = new RestRequest("api/serverdata/type/{datatype}", Method.GET)
{
RequestFormat = DataFormat.Json
};

request.AddParameter("datatype", type, ParameterType.UrlSegment);

var response = _client.Execute<serverdatamodel>(request);

return response.Data;
}

public ServerDataModelGetByIP(int ip)
{
var request = new RestRequest("api/serverdata/ip/{ip}", Method.GET) {RequestFormat = DataFormat.Json};
request.AddParameter("ip", ip, ParameterType.UrlSegment);

var response = _client.Execute<serverdatamodel>(request);

return response.Data;
}

public void Add(ServerDataModelserverData)
{
var request = new RestRequest("api/serverdata", Method.POST) {RequestFormat = DataFormat.Json};
request.AddBody(serverData);

var response = _client.Execute<serverdatamodel>(request);

if (response.StatusCode != HttpStatusCode.Created)
throw new Exception(response.ErrorMessage);
}

public void Update(ServerDataModelserverData)
{
var request = new RestRequest("api/serverdata/{id}", Method.PUT) {RequestFormat = DataFormat.Json};
request.AddParameter("id", serverData.Id, ParameterType.UrlSegment);
request.AddBody(serverData);

var response = _client.Execute<serverdatamodel>(request);

if (response.StatusCode == HttpStatusCode.NotFound)
throw new Exception(response.ErrorMessage);
}

public void Delete(int id)
{
var request = new RestRequest("api/serverdata/{id}", Method.DELETE);
request.AddParameter("id", id, ParameterType.UrlSegment);

var response = _client.Execute<serverdatamodel>(request);

if (response.StatusCode == HttpStatusCode.NotFound)
throw new Exception(response.ErrorMessage);
}
}


Create ModelClass

Under Solution Explorer, right click on Models folder and Add -> New
Item (or hit Ctrl + Shift + A). Choose class and name it
ServerDataModel
and click 'Add'. It will add an empty
Model
class.

Here is our complete
model
class:

Hide Shrink

Copy Code
public class ServerDataModel
    {
        public int Id { get; set; }
        [Required]
        [Display(Name = "Initial date")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime InitialDate{ get; set; }
        [Required]
        [Display(Name = "End date")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime EndDate{ get; set; }

        [Required]
        [Display(Name = "Order number")]
        public int OrderNumber { get; set; }
        [Required]
        [Display(Name = "Is dirty")]
        public bool IsDirty { get; set; }
        [Required, StringLength(15)]
        [Display(Name = "Data Server IP")]
        [RegularExpression(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)
        {3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$",
        ErrorMessage = "Data Server IP should be in the form of 255.255.255")]
        public string IP { get; set; }

        [Required]
        [Display(Name = "Record data type")]
        [RegularExpression(@"^([1-2])$", 
        ErrorMessage = "Record Data Type should be 1 or 2")]
        public int Type { get; set; }

        [Display(Name = "Record identifier")]
        [RegularExpression(@"^([0-9])$", 
        ErrorMessage = "Record identifier should be between 0 to 9")]
        public int RecordIdentifier { get; set; }
    }


Describing ModelClass

Here are some points we should notice in our
model
class:

Initial Date
and
End
 Date
should be of
Date
type and formatted as
MM/dd/yyyy
:

Hide Copy Code
    [DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime InitialDate{ get; set; }


Here, we are using Data annotations.
We set
ApplyFormatInEditMode = true
so, during edit mode, user shouldn't
forget to supply the required format.
Our date fields should contain
calendar
control on the browsers which
obeys HTML5 rules.



IP
should be formatted in the actual IP format (to avoid entering unwanted
string
s).

Hide Copy Code
[Display(Name = "Data Server IP")]
[RegularExpression(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)
{3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$",
ErrorMessage = "Data Server IP should be in the form of 255.255.255")]
public string IP { get; set; }


Here, we used
RegularExpression
, the app will throw an error if it
doesn't match.



Record data type
should be 1 or 2.

Hide Copy Code
[Required]
[Display(Name = "Record data type")]
[RegularExpression(@"^([1-2])$", ErrorMessage = "Record Data Type should be 1 or 2")]
public int Type { get; set; }


If expression does not match, it will throw an error message.



Record identifier
should be between 0-9.
If expression does not match, it will throw an error message.




Why All Checks Are At Client Side?

In this article, we are implementing ASP.NET WEB API in our client project which is in ASP.NET MVC4, here we want to make sure that each and every request should be verified and error-free. Three are lot of debates on this approach whether we implement are
client-side or at Services-side. In my view, services is the centralized process and it would be calling from multiple clients, so, it's the responsibility of each and every client that incoming request should be verified and error-free (here incoming request
does not contain any security logic, here I meant to say only about normal validation data checks).


Create Controller

Under Solution Explorer, right click on Controllers folder and click Controller.



From Add controller dialog, enter Controller name
ServerDataController
and
select MVC controller with empty read/write actions from Template dropdown, click on 'Add'.




Describing Controller

Our
ServerDataController
is going to consume ASP.NET WEB API using RestSharp(we'll use our helper class, created above).

Hide Copy Code
static readonly IServerDataRestClientRestClient= new ServerDataRestClient();


Above, we simply initialized our
ServerDataRestClient
.

Hide Copy Code
private IServerDataRestClient_restClient;

public ServerDataController(IServerDataRestClientrestClient)
{
_restClient = restClient;
}


Above is another flavor, where we need to use inversion of control (IOC).

Hide Copy Code
public ActionResult Index()
{
   return View(RestClient.GetAll());
}


In the above, our
Index ActionResult
method will get all
ServerData
records
from services and render our
view
. We need to add views at this point.


Create View

At this point, we need a UI, where we can show output or provide an interface to our user to interact with the application. So, we need to add a
view
.

The direct/rough way to add a view, from Solution Explorer, add a new folder ServerData and right click on it, then click on Add View.



From Add View dialog, name your view like
Index
, select
Razor
as
ViewEngine
,
create strongly typed view and select
ServerDataModel
as a
Model
class,
I use
Scaffold Template
of List (you can ignore if do not want to use), use your master layout and click on 'Add'.



It will add a new view to project.

Hide Copy Code
@modelIEnumerable<consumewebapi.models.serverdatamodel>

@{
ViewBag.Title = "Manipulate Server Data";
Layout = "~/Views/Shared/_Layout.cshtml";
}</consumewebapi.models.serverdatamodel>


We did a little bit of manipulation to get the output:

Hide Copy Code
@string.Format(item.IsDirty ? "Yes" : "No")


It will give us
Yes
or
No
showing
our Record is dirty or not.

Following same step(s) add other views, here is the structure:




Executing the Project

Finally, we are done with all of our customizations, changes, now it's time to run our project. Just click run or hit
F5
.
Our
Index
page will be rendered as:




Points of Interest

Ah! ASP.NET MVC4 is not providing direct implementation to use RestSharp. There is a good way to add
RestSharp
supports
to our project and then we can use this awesome framework.
I have created a demo app here, you can use this and
adapt the code as a part or whole. I will be glad to hear from you, if you find any issues or other things you need to handle.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: