I have been struggling on trying to work this for the last 3 days, how do you pass data from an api controller into an mvc controller and use the data to populate a selectlistitem.
I have seen plenty of examples of calling the api from the webpage which is all well and good, but what if the user has javascript disabled, it will not display the data.
So any help with an example for this would be much appreciated.
My code is:
web.api
public IEnumerable<DisplayCurrencyInDDL> GetCurrencyForDDL()
{
var s = _ICurr.InsetCurrencyIntoDataBase();
return s.AsEnumerable();
}
mvc controller
WebClient wc = new WebClient();
var s = wc.DownloadString("http://localhost:50687/api/Currency");
How do I get the value from var s (currency and currencyid) into a selectlistitem.
Thanks
George
edit data returned as: [ { "strCountry": "Afghan Afghani", "strCountryCode": "AFN" }, { "strCountry": "Albanian Lek", "strCountryCode": "ALL" }, { "strCountry": "Algerian Dinar", "strCountryCode": "DZD" }, { "strCountry": "Andorra Euro1",
I don't understand why you are doing it this way.
If you want to share some code you can do this by moving the code into
some Library and instantiate that class in WebAPI and also in your MVC
Controller.
Ok, so after reading this post on stackoverflow difference between apiController and controller
Its my understanding that if i'm returning data to my own website, then use mvc controller, but if i'm allowing a 3rd party to consume data from my site, then put the data in an api controller.
Also if a user visited my site/your site and had javascript disabled, then json would not work on the client side as requires jQuery etc, so my understanding is use api if you are sure the visitor will not have javascript disabled.
Please let me know if that correct
Related
I have a question about MVC asp.net
I have a link that provides a data using HTTP in this XML format
[...]
<Item>
<Name>Money</Name>
<Unit>1000</Unit>
</Item>
[...]
If I want this to display data on view in my application - what should I use? WebAPI?
The data ( < unit > ) change every few minutes, so always view have to display the current data.
Data are also possible to get in JSON format.
To clear up the confusion from all existing answers and comments: your actual problem statement is this:
I have a third-party URL that when requested, gives you some JSON which I wish to display in a table on an MVC view.
This is very trivial. See Deserializing JSON into an object to generate classes to deserialize the JSON. This provides you with a statically typed class that you can use from code.
Then you define a view model to hold a list of items:
public class JsonViewModel
{
public List<JsonItem> Items { get; set; }
}
public class JsonItem
{
public string Name { get; set; }
public string Unit { get; set; }
}
And in the controller you perform an HTTP GET request to retrieve the JSON (HTTP GET request and XML answer), parse it, map it to your view model and return it to your view:
public class FooController : Controller
{
public ActionResult Index()
{
// 1. Perform HTTP request to retrieve the JSON.
var webClient = new WebClient();
string rawJson = webClient.DownloadString("json-url");
// 2. Parse the JSON.
var jsonRootObject = JsonConvert.DeserializeObject<JsonRootObject>(rawJson);
// 3. Map to your viewmodel
var viewModel = new JsonViewModel
{
Items = jsonRootObject.Items.Select(i => new JsonItem
{
Name = i.Name,
Unit = i.Unit
}).ToList()
};
// 4. Return the model to your view
return View(viewModel);
}
}
Then finally you render the model in your view:
#model JsonViewModel
<table>
<tr>
<th>Name</th><th>Unit</th></tr>
</tr>
#foreach (var item in Model.Items)
{
<tr>
<td>#item.Name</td><td>#item.Unit</td>
</tr>
}
</table>
In your controller, call the external service to get the data. Can be XML, but JSON is more lightweight; I'd go for that. Parse the data into a view model that you then pass to the view. The view model contains the parsed information in the format that is best suited for your view; this will make sure your view can be kept as simple as possible (focusing on view logic).
To keep your controllers light, you might want to decide to move the retrieval and parsing logic in dedicated components, and use those from within your controller.
Basically, what to use - JSON or View - is fully up to you and depends on your knowledges.
You can reach what you need here using JSON(or even XML) and js code in the page, or partial view and less js code.
I'd suggest you to return partial view from your MVC controller and update whole block.
You can simply use a periodic ajax call using setInterval to the 3rd party endpoint and then update your view accordingly.
A better approach would be to use MVVM so you just need to update the view model and the framework will do the rest.
If you want to decouple your site from the 3rd party or you just want to hide that 3rd party address, You can use Web Api to call the 3rd party endpoint and call the web api endpoint from the client.
You will need to handle CORS this way, if the web api is in a different domain.
You can also use mvc action instead of the web api but if you're planning on building large scale application. It's better that you start using SOA Architecture.
I prefer Json instead of Xml because it is lightweight, so... you can go through three different ways:
Create a method that returns a JsonResult in your Controller (that is what i think you are doing) inside your asp.net mvc application;
Create a WebApiController inside your asp.net mvc application just to have the web api stuff without creating a new application;
Create a Web Api application and return your data (if you need only one service, i don't think you should create a new app for that, it is too much work)
If you choose the third option and you are not familliar with Web Api, i will recommend you to read this.
I'm not sure of the best way to accomplish my goal. Looking for insight. I'm familiar with WebAPI services consumed through WPF and Silverlight but this is my first run at ASP and MVC.
I am building a site to verify contents of a shipment against an electronic manifest (EDI 856). I have a page that displays the shipping data and I need the users to scan each item barcode in the container. I would then like to pass that barcode to a service, verify the item belongs in that shipment and then update the page to show as much.
My plan was to have a single text box into which the user could scan/type the barcode and then submit that data to a WebAPI service which would verify the information and then probably use SignalR to send a message back to the page and update a grid with the item data.
If this is a decent way to go, I'm just not quite sure how to use ajax to call the WebAPI endpoint and provide the data I need.
I would advise against using SignalR in this situtation. What you need, judging from your description, is the most basic use case of submitting an ajax request and receiving a response.
You are not designing a system where you need the server to initiate communication with the browser or anything like that, where sockets (and SignalR as an abstraction over sockets with fallbacks to less suitable protocols) is a huge overkill.
Don't worry, your use case is rather simple.
It's a little out of scope to describe how to setup a WebApi project, how to configure routing, action names, etc. Simple google searches will surely provide ample quality tutorials on getting started.
I'll just try to explain what the general idea is, with some code samples, to get you thinking in the right direction.
You need to create an ApiController.
The simplest version of that Controller will probably look something like this:
public class ShipmentVerificationController : ApiController
{
//this is the response object you will be sending back to the client website
public class VerificationResult
{
public bool Valid;
}
public VerificationResult GetIsItemValid(string BarCode)
{
bool itemIsValid;
// Implement checks against the BarCode string here
itemIsValid = true;
return new VerificationResult { Valid = itemIsValid };
}
}
Note that the inner class represents the response you will be sending back. It should be properly filled out with additional info if needed and probably put into a separate .cs file in the "Models" folder or where ever you see fit.
I have declared it inside the controller for demonstration purposes only
Once you have a WebApi service deployed, it's really easy to send it data from your website and receive the feedback.
To simplify Ajax requests, jQuery is often used.
Once the user inputs the barcode into a textbox, you can hook up an event to check for return key being pressed (most barcode scanners send the return key command after they input the barcode data) and then write something along the lines of:
var barcode = $("#input-field").val();
$.getJSON( "<url_to_your_webapi_service>/api/ShipmentVerification/GetIsItemValid/" + barcode, function( data ) {
if (data.Valid) {
// great, highlight the item as valid
}
else {
//better indicate an error with the scanned item
}
});
Please note that for simplicity I have not included any error handling, url parameter encoding, and most importantly, zero authorization.
Authorization is very important if you deploy the web service to the open web but still do not want anyone to be able to call it.
You will have to research these topics yourself, but I hope I have presented you the core concepts and logic behind a simple service such as this, so you have a base to start with.
If you come up with specific problems and questions post a new question.
I actually found a more simple way to do this. I nixed the idea of using a WebAPI endpoint and just went with a normal controller. I used ajax to prevent the page from refreshing with the new view, since that view is actually just json data with my return values in it.
I'm rewriting some old application, written in ASP.NET MVC. It used authentication by LDAP, but now it is necessary to rewrite it to OAuth2. I've decided to use DotNetOpenAuth library as it looked like best choice, but I'm stuck on auth response.
Currently, I have one controller class called AccountController, containing some methods, but most important are RedirectToIS and PostAuth (which is an redirect uri):
public ActionResult RedirectToIS()
{
DotNetOpenAuth.OAuth2.AuthorizationServerDescription asd = new DotNetOpenAuth.OAuth2.AuthorizationServerDescription();
String site = ConfigurationManager.AppSettings["oauth:site"];
asd.AuthorizationEndpoint = new Uri(site + "/oauth/authorize");
asd.TokenEndpoint = new Uri(site + "/oaut/token");
asd.ProtocolVersion = DotNetOpenAuth.OAuth2.ProtocolVersion.V20;
this.oaclient = new DotNetOpenAuth.OAuth2.WebServerClient(asd, ConfigurationManager.AppSettings["oauth:appid"], ConfigurationManager.AppSettings["oauth:secret"]);
this.oaclient.RequestUserAuthorization(null, new Uri("http://localhost/Account/PostAuth"));
return View();
}
The PostAuth method is what I am trying to make to work correctly. It is page, where the OAuth2 server redirect user after successful authorization with code and state GET parameters. Because I'm trying to utilize library and not (re)write it, I've stuck here - I don't know what to do now.
I tried, as I've seen in one example, use DotNetOpenAuth.OAuth2.IAuthorizationState st = this.oaclient.ProcessUserAuthorization(); in PostAuth, but it don't work. In example author had original WebServerClient instance, but I can't achieve it with Session nor using AccountControler data item.
So, finally, my question: How to transfer object oaclient from RedirectToIS method to PostAuth method (some kind of session?) or how to start using OAuth?
PS: I'm not new to C#, but I've never used ASP.NET.
Since a few days I'm trying to create my own web api controller. Duo to the rest conventions I need to use a post request to create an object. To get concrete, Im having this controller with this action:
public class ReservationController : ApiController
{
[HttpPost]
public void Create(int roomId, DateTime arrivalDate)
{
//do something with both parameters
}
}
This code is not working when I fire a post request at it, I'm receiving a 404 exception something like this:
No action was found on the controller 'Some' that matches the request.
The reason for it is that simple types are read from the query string, complex types from the body, according to this aricle. The web api uses the parameters to match the action to a request and can't therefore map my action to the request.
I do know that I can use the [frombody] tag, but you can only apply that to one parameter and I have 2. I also know that I can create a wrapper object which have both the parameters, but I'm not willing to use wrappers for all my calls.
So I do know that I can work around this by these methods. I also think that this is caused by the fact that the body of the post request can only be read once. But my actual question is:
Why is the source of a parameter determined by it's type and not by it's availability, especially when the conventions state that you should make for example a post request for creation? In MVC this is the case, why isn't it in the web api?
Best regards,
BHD
FINAL UPDATE
Since I'm getting some upvotes, problably more people are facing the same question. In the end it comes to this: Web-Api != MVC. It's simply not the same thing and the web api team made different design decisions than the mvc team I guess.
It seems that you have a fundamental misunderstanding of how Web API actually works.
Web API routing is driven off of verbiage, not the method names. "SomeMethod" actually translates to zero useful information for Web API. As a result, if I post
api/some/some?id=1
OR
api/some/somemethod?id=1
OR EVEN
api/some/?id=1
and the SomeMethod endpoint is the ONLY available POST, it will hit that endpoint.
As such, first of all, make sure you have only one POST on that api controller. If you do, POSTing to it from any test client using either of the query strings above will work just fine.
You can use the [FromBody] attribute on the parameter to force it to read from the body of the HTTP POST instead of the Uri. This is opposed to the [FromUri] attribute which does the opposite.
[HttpPost]
public void SomeAction([FromBody] int id)
{
//do something with id
}
Are you sure you're actually putting the id in the body? It could also be a routing issue. If this still doesn't work then maybe you should use Fiddler and copy the RAW output of your HTTP message here.
If you're packing multiple values into the body such as with JSON then you should use a model which should automatically be deserialized to:
public class PostModel
{
public int ID { get; set; }
public int SomeOtherID { get; set; }
}
[HttpPost]
public void SomeAction(PostModel postModel)
{
//do something with postModel.ID and postModel.SomeOtherID
}
You can actually do this straight out of the box in WebAPI, at least in 2.2 (.Net version 4.5.2). Your controller is correct. Using your controller, if you call it with a HTTP POST like this (tested through Fiddler):
http://localhost:58397/api/Reservation?roomId=123&arrivalDate=2015-12-17
You'll get the correct values of roomId = 123 and arrivalDate = 17.12.2015.
I suspect there's something wrong in your call to the WebAPI. Maybe post that call if you're still not getting it to work.
I am working on exposing some REST-based services via ASP.NET MVC 3. These services will be hit via JQuery as well as a Windows Phone Silverligh app. I know how to interact with a typical service. For instance, I currently have ones like the followng:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddComment(string username, string comment)
{
// Do stuff
return Json(new { message = "Success" });
}
I want to expose a REST-based service that allows users to upload a file. The trick here is that I also need to pass some data along with each file. However, I'm not sure how to do that. Every example I find only has just a file. But I'm not sure of
How to accept additional data
What to pass from JQuery.
Everything else I passed is just strings. However, in this I seem to have data serialized in binary format because of the file, and some string text. Because of that, I'm not sure what to do. Am I making sense?
The signature for the action should just be:
public ActionResult MyAction(string username, string comment, HttpPostedFileBase file1)
{ ... }
MVC binding should examine the request and match the form submission to the action based on the parameter names and types.
The clientside form must have enctype = "multipart/form-data" with method POST.
JQuery would just post the form with $("#form").submit().