How to send list as parameter for search in angular service to .net core - asp.net

Please Help me I need to retrieve a list of details using a list of parameters. How to achieve that from angular 10 and .net Core?
Also, Single Entries is working for search. But If I try to enter a second entry in the input field and tried to search it is not working.
The method name is GetPodForwardings.
This is the Method in angular (Service)
GetPodForwardings(conNo,newPage,pageSize)
{
return this.http.get(`${this.BaseUrl}Pod/GetConsignmentList?conNo=${conNo}&newPage=${newPage}&pageSize=${pageSize}`)
}
In .NET Controller
[Microsoft.AspNetCore.Mvc.Route("GetConsignmentList")]
[HttpGet]
public async Task<IActionResult> GetListofConsignments([FromQuery]List<long> conNo,int currentPage,int pageSize)
{
return await ProcessQuery(new GetListofConsignmentByConsignmentNoQuery(conNo,currentPage,pageSize));
}

The proper way of adding parameters to an url in Angular is to use the second options parameter of the http.get("url",options) function. Unfortunatly they don't accept arrays rightaway (there is an open github issue).
However string interpolation like you did should also work. You seem to just have the wrong format. As this is treated very framework specific look at this answer to get the right format for your case.

Related

ASP.NET MVC (WEB API) with angular JS passing strong type parameters

So I have a controller takes strong typed CarModel object for post request.
In angular js how do I serialize it and pass with post request so the controller will understand it.
Can someone show a sample code or point to a right direction.
I have only seem people posting on how to pass data for angular js to read it, did not find anything talks about how to post a strong typed object.
Thanks
[HttpPost]
[Route("someUrl")]
public IHttpResult PostObject([FromBody]Type name){
return Ok();
}
And from angular
$http.post("someUrl", myObject);
The javascript object is serialized by angular. The property names just have to match.

How to make a controller accept post data from the body as well as URL in MVC 6 ASP.NET 5

Currently I am trying to write a controller in MVC 6 that is capable of accepting data from a post request. The issue is that depending on the client (which is not always a web browser), the data can come in as either key value pairs in the request URL, or as JSON in the request body.
Currently this method works for accepting the data from the URL:
[HttpPost]
public async Task<CaptureResponse> CaptureData(CaptureInfo capture) {
...
}
After a lot of trial and error (and stack overflow answers), I figured out that the [FromBody] attribute tells the model binder to look in the request body, which is required now because MVC 6 combines WebApi and standard MVC together. The following code parses data from JSON in the form body:
[HttpPost]
public async Task<CaptureResponse> CaptureData([FromBody] CaptureInfo capture) {
...
}
For simplicity, I would like to combine the two together somehow, so the model binder gives me the data in the same parameter variable. So far, the only way I can get the data into the same Action is to specify two parameters, one for the URL and one for the body, and do some null checking on each like so:
[HttpPost]
public async Task<CaptureResponse> CaptureData(CaptureInfo capture, [FromBody] CaptureInfo bodyCapture) {
if (bodyCapture != null) {
if (bodyCapture.RequiredProperty1!= null
&& bodyCapture.RequiredProperty2!= null) {
capture = bodyCapture;
}
}
...
}
I have tried specifying multiple properties before the input attribute like this:
[HttpPost]
public async Task<CaptureResponse> CaptureData(CaptureInfo [FromQuery][FromRoute][FromForm][FromBody] capture) {
...
}
But it does not work. Any ideas if something like this is possible?
As far as I know, it is just not possible. Of course you can try using workarounds, basically doing all request parsing yourself. It doesn't sound good, does it?
If you really want the things your way, I believe the best approach is to have two distinct endpoints in the controller and the private method for actual processing. Or, perhaps, even extract that method into an additional abstraction layer with BlaBlaService (CaptureService in your case, probably) class(es) responsible for all the dirty work. Sometimes it makes sense to separate your controllers layer from business logic - for example, for testing purposes.
PS: Your idea is quite similar to what was the approach in good old .NET & PHP times, and believe me, this particular idea is not the one that made those times good. You know, the MVC is much about the REST-like approach, so each endpoint of your controller is supposed to be dedicated to its own single function and obey to a single and uniform "intuitive" protocol.
The "intuitive" way to submit data to POST request for developers acquainted with REST is through the request body. I suggest you to consider going with this approach as the only one.
You need use Request.Form
like:
string username = HttpContext.Current.Request.Form.GetValues("key1")[0].ToString();
string password = HttpContext.Current.Request.Form.GetValues("key2")[0].ToString();
string something = HttpContext.Current.Request.Form.GetValues("key3")[0].ToString();

Web API Complex Data in Get

I am using Web APi, as I am new to this, I dont know much about it.
I am trying to implement search, as of now I am starting with only text search, but later there may be huge search criteria. for one text that is easy, as web api works good with
primitive data types. Now I want to create a class of filter, say the pagenumber , the pagesize also all the search criteria, so I created a class. I have created a MVC application which is communicating with the web api, the web api returns Json data, then I de-serialize it to model. I am stuck with the complex object part, also as of now I am using a list to get the data, later that will be replaced by data base. Following is the code.
public IEnumerable<Document> Get(PaggingDetails request) //public async Task<IEnumerable<Note>> GetNotes() for Async (DB)
{
return _repository.GetAll(pagedetails.PageNumber, pagedetails.PageSize, pagedetails.PageFilter);
//return await db.Notes.ToListAsync<Note>(); for async
}
public string GetPage(int pagenumber,int pagesize,string pagefilter)
{
try
{
PaggingDetails PageDetails = new PaggingDetails();
PageDetails.PageFilter = pagefilter;
PageDetails.PageSize = pagesize;
PageDetails.PageNumber = pagenumber;
return new System.Net.WebClient().DownloadString
("http://.../api/Document/?pagedetails=" +
PageDetails);
//new HttpClient().GetStringAsync("http://localhost:18545/api/Emails"); for async
//also pass parameters
}
catch (Exception ex)
{
}
return "";
}
By deafult, you cannot use a class as the type of parameter of a GET Web API action. You need to use individual parameters of single types.
If you want to use a class as parameter nothing stops you to use a POST action, in which you can include the data without any problem.
However you can force a complex parameter of a GET action to be read from the URI by decorating the comples attribute with [FromUri].
You can read this document to better understand Web API parameter binding:
Parameter Binding in ASP.NET Web API
By default, Web API uses the following rules to bind parameters:
If the parameter is a “simple” type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)
For complex types, Web API tries to read the value from the message body, using a media-type formatter.
This is the standard way of working. If you use the [FromUri] attribute, the action selector won't be able to choose between different Get methods that receive different complex types. If you use a route with controller and action segments, you won't have that problem, becaus ethe actions selector will choose by action name, no matter what the aprameters are.
I don't like using the [FromUri] for this reason, and beacuse it's not the natural way to work with the GET action. But you can use it with the necessary precautions.

asp.net webapi mapping a string param that has a querystring

I need to map a string param with a webapi method. Something easy:
/api/mycontroller/this_is_my_input_param
I know how to do it and it's working fine. However, problem is that my input param can have a query string. Something like:
/api/mycontroller/term?p=1&n=value
and I want that webapi map the entire "term?p=1&n=value" with the input param in the method. I just wanna tell webapi "ey, just take all the string you have after /api/mycontroller/ and send it to the action as input parameter"
I know that probably is not the best architectural thing, but I need it that way. Also, I don't know how many params and names I can have, so I can't use a complex type. I also need it as a GET. I know how to do it with a POST, but I need a GET if it's possible.
Many thanks.
Can you able to add that querystring to body and then by using (frombody/ fromuri) attributes
to grab the querystring and do whatever you want
Route[api/mycontroller/term]
public HttpResponseMessage myController([fromBody] querystring)
{
// do something for that querystring
}
please check webapi attributes from this link
enter link description here
Finally what I'm doing is mapping the entire HttpRequest, that way I can work with the full requestted URL and get all that I have after the Controller name:
public async Task<string> Get(HttpRequestMessage request)
I know would be better to create a custom ModelBinder or something like that, but in my case is enough doing it that way.
thanks for your help.

Need help designing to ASP.NET MVC action methods

I'm just starting out learning ASP.NET MVC 3. I've been going through the Music store sample on the ASP.NET website, as well as starting to develop my own site, but I'm having some trouble understanding how I should setup my controller action methods.
On my site each user that is logged in will be able to perform standard CRUD operations on their Projects. I've set this up similar to the Music Store sample with the following action methods on a ProjectController. So far this makes sense to me.
ActionMethod View
ProjectController.Index() Lists the active users's projects
ProjectController.Details(int id) Shows details for project 123
ProjectController.Create() Shows a form to edit a new project
ProjectController.Create(FormCollection col) Adds a new project with the form contents
ProjectController.Edit() Shows a form to edit a new project
ProjectController.Edit(int id, FormCollection col) Adds a new project with the form contents
ProjectController.Deiete(int id) Shows a delete confirmation form
ProjectController.Delete(int id, FormCollection col) Deletes a project with the provided id.
In addition, users will be able to add Items to each project. Items can not exist on their own and must be associated to a project when being created. What I'm having trouble understanding is how to pass along the reference to the project an Item should be created in. For example in my item controller I have a pair of Create() action methods similar to the controller above.
ItemController.Create() Shows a form to create a new item
ItemController.Create(FormCollection col) Creates a new item with the details from the form.
Yet I don't understand how the first Create() method passes a reference to the project which the new Item should be created in since the View() helper method can only accept one object parameter. Should I just add a reference to a project to a property of the ViewBag? I'm new to dynamic types as well and the ViewBag just seems magic to me at the point. So I'm a little hesitant to use it. I've also always thought strongly typed design is better. So should I create a separate "NewItemData" model object that contains a reference to a new Item as well as the project it is being added to?
Once the form knows which project it is adding an item to how should it pass this information back when submitted? Should there be a hidden "ProjectID" field in the form? Or should the form POST back to a URL with the project id in the query string?
www.mysite.com/Item/Create?ProjectID=1234
Finally, I also want to be able to list the items that are added to each project. Should this be part of the ItemController or the ProjectController. For simplicities sake I'm sticking with the default Controller\Action[ID] URL routing. A few of my ideas are listed below. I'm leaning towards the last option, but would really like to hear what others with more experience with this stuff think.
Action Method URL
ItemController.Index(int ProjectID) \Item?ProjectID=1234
ItemController.List(int id) \Item\List\1234
ProjectController.Items(int id) \Project\Items\1234
To answer your last question, it depends. Do Items in your model exist independently of a project? If the answer is no, then I would tend to do
ProjectController.AddItem(int id)
ProjectController.Items(int id)
where id represents the projectID.
The name of the parameters you use in the action signature directly correspond to values from the routedata and request values. {controller}/{action}/{id} is a pattern that uses the braced names as keys in the route dictionary. If you wanted you could change the routes to be {controller}/{action}/{projectid} for that action and your method signature could be the (int projectid) signature.
I don't recommend you do this just to get awesome signatures. Use comments instead if you think people will get confused.
Without changing the route pattern, if you would prefer your urls to be /project/items?projectid=3 than /project/items/3 then the action would be this:
ProjectController.Items(int projectId)
I like the prettier urls, so i'd be more apt to use the id version. That being said, if Items do not exist independently of the Project object, I would be be more likely to do this. However, if you are going to have a TON of different actions that can be performed on an Item, it would make sense to separate them into ItemController and ProjectController.
It comes down, to a large extent, about what makes sense for your application and how many actions you think a controller should have on it.
In this case you'd create a hidden field with the name=projectId and then in your Create controller have an action method.
[HttpPost]
public ActionResult Create( int projectId, FormCollection postData )
Usually you'd also use a strongly typed viewmodel so instead the FormCollection parameter use:
[HttpPost]
public ActionResult Create( int projectId, Item or ItemViewModel postData )
And as long as the name attributes match the properties in Item or ItemViewModel MVC's ModelBinder will take care of hydrating those values.

Resources