Under one colution file I have couple of projects.UI (ASP.Net mvc) project, A project for my rest services, A DTO project, A business logic project and Data Access. Now my services projects's controller needs to talk with my UI(ASP.Net MVC) project's controller and get the data entered in the form and send it to the database. Im quite unsure of the logic I should come up with inside the controller class of the UI project. The UI project sepratley has entity classes as well. Help needed!!
This is the POST method in my services controller
// POST api/Maintenance
[HttpPost]
public IHttpActionResult Post([FromBody]Maintenance maintenance)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
maintenanceLogic.Insert(maintenance);
return CreatedAtRoute("DefaultApi", new { id = maintenance.WorkID }, maintenance);
}
This is the method that will access the above methods uri.This method is in the controller class of my UI project. I came up with a logic.But I think its not correct.
[HttpPost, Route("/maintenance/CreateMaintenanceOrder")]
public PartialViewResult CreateMaintenanceOrder([FromBody] Maintenance Model)
{
Model.CheckItems = maintenanceViewModel.CheckItems;
Model.CrewMembers = maintenanceViewModel.CrewMembers;
Model.WorkID = ++SessionUtility.CurrentMaintenanceID;
try
{
var uri = "api/Maintenance/Post ";
using (HttpClient httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://localhost:8961");
Task<String> request = httpClient.GetStringAsync(uri);
Model = JsonConvert.DeserializeObject<List<Maintenance>>(request.Result);
}
maintenanceViewModel.MaintenanceOrders.Add(Model);
}
catch (AggregateException e)
{
}
maintenanceViewModel.MaintenanceOrders.Add(Model);
return PartialView("_Search", maintenanceViewModel);
}
You are trying to call a Post method using GetAsync as well as it seems you are not passing the Maintenance object required by Rest service method as input. Please try below -
string maintenanceData = JsonConvert.SerializeObject(Model); //considering you have to pass Model as input to Rest method
HttpResponseMessage response = httpClient.PostAsync(new Uri("http://localhost:8961" + "api/Maintenance/Post/"), new StringContent(maintenanceData));
Related
I have two solutions one is an MVC5 web app and the other is an MVC core 2.2 web app that acts as a basic web form.
I am trying to post the webform data (using a ViewModel) to the MVC5 web app API.
The Code
The POST method on the MVC5 web app/api
// POST
[HttpPost]
public IHttpActionResult Post([FromBody] WebFormDataVM personData)
{
// logic here
}
The MVC core webform (posting to the above)
[HttpPost]
public async Task<ActionResult> Create(PersonVM personData)
{
var path = "api/WebForm/Post";
var url = new Uri("http://localhost:60291/");
var client = new HttpClient();
client.BaseAddress = url;
var response = await client.PostAsJsonAsync(path, personData);
return RedirectToAction("Index");
}
The Issue
When posting the viewmodel the POST method API parameter (WebformDataVM personData) is always null.
I have tried the exact same setup but using an MVC5 project/solution instead of core and it works without fail.
What i have tried
Posting a string instead of view model object
Removing HTTPS from the .net core project (via the project options)
Any help would be greatly appreciated.
you should srialize your object to json
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var url ="yourUrl" // http://localhost:60291/api/WebForm/Post
var model=yourObject; //PersonVM
HttpResponseMessage response = await client.PostAsync(url, new StringContent(JsonConvert.SerializeObject(yourObject),Encoding.UTF8, "application/json"));
}
Please try with this solution
[HttpPost]
public async Task<ActionResult> Create(PersonVM personData)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:60291/api/WebForm/Post");
var response = await client.PostAsJsonAsync("personData", personData);
return RedirectToAction("Index");
}
}
[HttpPost]
public IHttpActionResult Post(WebFormDataVM personData)
{
// code
}
I have to retrieve orders from my API made in NET Core.
The retrieval is made in an action of my MVC controller calling an endpoint of another NET Core APP using GET.
The API endpoint is the following one:
API:
[HttpGet("orders/orderSearchParameters")]
public IActionResult Get(OrderSearchParameters orderSearchParameters)
{
var orders = MenuService.GetMenuOrders(new GetMenuOrdersRequest { From = orderSearchParameters.From, To = orderSearchParameters.To, FoodProviderId = orderSearchParameters.FoodProviderId }).Orders;
return Ok(orders);
}
An action of my Web App MVC controller must call that endpoint, and for that this is the following code:
public IActionResult GetOrders(OrderSearchParametersModel orderSearchParameters)
{
var uri = string.Format(ApiUri + "menus/orders/");
using (HttpClient httpClient = new HttpClient())
{
var response = httpClient.GetStringAsync(uri);
if (response.IsCompleted)
{
var orders = JsonConvert.DeserializeObject<List<OrderModel>>(response.Result);
return Ok(orders);
}
else
{
return BadRequest();
}
}
}
What I canĀ“t find is how can I serialize OrderSearchParametersModel to perform the GET operation with the HttpClient in the MVC controller.
In the attached code I do the GET without the incoming object.
How can I send this object using GET operation with HttpClient?
If you put all your parameters in the querystring, they will be translated into an OrderSearchParametersModel but they need to match this model properties names.
I have an MVC project that is exposed externally. I have an internal Web API project.
For reasons beyond my control, I cannot expose the Web API project directly and I cannot add Web API Controllers to my MVC project.
I need to create an MVC Controller that will act as a proxy for a Web API Controller. I need the response from the MVC Controller to look as if the Web API was called directly.
What is the best way to accomplish this?
Is there a better approach than what I have so far?
How can I fix the error that I am getting?
Here is what I have so far:
MyMVCController
[HttpGet]
public HttpResponseMessage GetData(HttpRequestMessage request)
{
...
var response = proxy.GetData();
return request.CreateResponse();
}
MyProxyClass
public HttpResponseMessage GetData()
{
...
return HttpRequest(new HttpRequestMessage(HttpMethod.Get, uri));
}
private HttpResponseMessage HttpRequest(HttpRequestMessage message)
{
HttpResponseMessage response;
...
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(120);
response = client.SendAsync(message).Result;
}
return response;
}
In the MVC Controller, I am getting an InvalidOperationException on the request.CreateResponse() line. The error says:
The request does not have an associated configuration object or the provided configuration was null.
Any help would be greatly appreciated. I have searched Google and StackOverflow but I haven't been able to find a good solution for creating this proxy between MVC and Web API.
Thanks!
You can do it by just creating some JsonResult action in your controller which will return result of calling web API.
public class HomeController : Controller
{
public async Task<JsonResult> CallToWebApi()
{
return this.Content(
await new WebApiCaller().GetObjectsAsync(),
"application/json"
);
}
}
public class WebApiCaller
{
readonly string uri = "your url";
public async Task<string> GetObjectsAsync()
{
using (HttpClient httpClient = new HttpClient())
{
return await httpClient.GetStringAsync(uri);
}
}
}
I have a simple Azure Worker Role in which I want to host Web API. I would like to setup the Web API controllers so that I can access them same way as a jQuery post so that I don't have to create shell classes and my Web API can remain flexible for use with jQuery in the future.
Q: How can I post from a C# client to a self hosted Web API controller in a worker role, without using shell classes?
I've worked with Web API in the past where it's hosted in a regular ASP.NET project and I am able to access it via jQuery doing something like this:
//Web API Controller
public class TestController : ApiController
{
public void Post(string item, string action)
{
//...
}
}
//jQuery
$.post("/api/test/", { item: "myItem", action: "someAction" }, function (data)
{
//...
}
For my worker role project, I followed the instructions on ASP.NET for Host ASP.NET Web API 2 in an Azure Worker Role and set up WebAPI. I'd like to be able to access the controller the same way from a C# client. However, the documentation on ASP.NET for Calling a Web API from a .NET Client uses classes, rather than individual variables. The code samples end up looking something like below. Edit: I have been able to successfully use this method to communicate data to the worker role.
//Shell Object
public class ShellObject
{
public string item;
public string action
}
//Web API Controller
public class TestController : ApiController
{
public void Post(ShellObject shellObject)
{
//Unpack object, then do action
//...
}
}
//C# Client
ShellObject shellObject = new ShellObject() { item = "myItem", action = "someAction" }
var response = await client.PostAsync("api/test/", shellObject);
Because I don't want to create unnecessary shell classes in multiple places in my code, I'd like to do something like below. Doing it this way also keeps my Web API flexible so that it can be used from a web based jQuery project in the future (which in my case is a very possible scenario). However, these methods doesn't work; the server returns a "Method Not Allowed" or the post just hangs. Additionally, the posts don't seem to be showing up in Fiddler. Edit: Additionally, because this is intended to be a general purpose server, it's possible for the Worker Role and the calling C# client to be in different solution, so that they cannot share class definitions. Additionally, serializing to JSON before the post is fine, as long as there isn't a need for shell classes.
//Web API Controller
public class TestController : ApiController
{
public void Post(string item, string action)
{
//...
}
}
//Simple Post
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["item"] = "myItem";
data["action"] = "myAction";
var response = wb.UploadValues("http://workerroleaddress/api/test/", "POST", data);
}
Q: How can I post from a C# client to a self hosted Web API controller in a worker role, without using shell classes?
Could this solve your problem?
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://test.myapi.com");
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(new { action = "myAction", item = "myItem" });
client.PostAsync("api/test",
new StringContent(json, Encoding.UTF8, "application/json")).Wait();
}
You could also use other serialization methods mentioned here.
So there is a heap of examples around but finding ones that are relevant to the rtm bits seems to be a little harder to find.
I have 2 projects one is an WebApi & the other is MVC4 .net 4.5 application.
I want to make a make an update to an item
I have a controller within my API that does something like
[HttpPut]
public MyModel Update(MyModel model)
{
//make update
return model;
}
Is this correct? should I be using a HttpResponseMessage instead of just using my MyModel class? I want to return the correct httpstatus details as much as possible as I am wanting to open up this api to 3rd parties not just my application
Calling this api from my mvc application from my controller how do I do this?
The beste way is to use HttpResponseMessage like this:
[HttpPut]
public HttpResponseMessage Update(MyModel model)
{
if(notfound)
{
return this.Request.CreateResponse(HttpStatusCode.NotFound);
}
//make update
return this.Request.CreateResponse<MyModel>(HttpStatusCode.OK, Model);;
}
I mostly use EasyHttp if I want want to call a WebApi method from my MVC app:
var model = new ExpandoObject(); // or use a stronly typed class.
model.Id = 1,
model.Name = "foo"
var http = new HttpClient();
http.Post("url", model, HttpContentTypes.ApplicationJson);
If you want to respond with httpstaus code you have to return HttpResponseMessage.
You may choose to have a common method returning your BOs and call it from the Action and from your other mvc application code. Then your rest calls would always be wrapped with a status code and other calls get an object.
[HttpPut]
public MyModel Update(MyModel model)
{
return base.Request.CreateResponse<MyModel>(HttpStatusCode.OK, UpdateModel(model));;
}
[NonAction]
internal MyModel UpdateModel(MyModel model)
{
//make update
return model;
}