How to convert formcollection to model ins ASP.NET MVC - ajax

I have a model class called ClientPackage and in my controller action method i receive a FormCollection from an ajax post call that i would like to convert it to the model class ClientPackage.
public class ClientPackage
{
public int DemandeId { get; set; }
public string NumeroRequette { get; set; }
public string NumeroModification { get; set; }
public int CasId { get; set; }
public string NumeroDossier { get; set; }
public string NomPatient { get; set; }
public string PrenomPatient { get; set; }
public string NiveauPriorite { get; set; }
public int NiveauPrioriteId { get; set; }
public Unite UniteDepart { get; set; }
public Unite UniteDestination { get; set; }
public Demandeur DemandeurDepart { get; set; }
public Demandeur DemandeurDestination { get; set; }
public ConditionTransport ConditionTransport { get; set; }
public Transport Transport { get; set; }
}
[HttpPost]
public string AjaxCall(FormCollection formData)
{
ClientPackage package = (ClientPackage)formData; //exception error
}
I would appriciate any help

Instead of trying to convert you can use the FromForm attribute and receive your model as a parameter.
[HttpPost]
public ActionResult CreateClientPackage([FromForm] ClientPackage clientPackage)
{
...
}

Here is how I post models with ajax.
<script>
function PostForm() {
var model = $('#your_form_id').serialize();
$.ajax({
url: '/YourController/AjaxCall',
type: 'POST',
data: model,
success: function (data) {
},
error: function (request, error) {
console.log("Request: " + JSON.stringify(request));
}
});
}
</script>
and in your controller.
[HttpPost]
public string AjaxCall(ClientPackage model)
{
//no need to cast the model to a ClientPackage
//ASP.NET mvc will do it for you as long as you send a serialized form that represents a ClientPackage object
}
Hope this helps!

Related

Web Api take an array from front

The question is very simple :-).
I'm a beginner.
Data comes to the controller (WebApi).
If you put an object.
[HttpPost]
public async Task<IActionResult> AddOrder(Object [] orderR)
ValueKind = Object : "{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-
08d8db1aac26","code":"666666","name":"test6","price":6,"category":"test6","orrderItems":"320d57eb-
3333-45d2-f497-08d8d66a0d39"},"quality":1}"
ValueKind = Object : "{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-
08d8db1aac26","code":"666666","name":"test6","price":6,"category":"test6","orrderItems":"320d57eb-
3333-45d2-f497-08d8d66a0d39"},"quality":1}"
ValueKind = Object : "{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-
08d8db1aac26","code":"666666","name":"test6","price":6,"category":"test6","orrderItems":"320d57eb-
3333-45d2-f497-08d8d66a0d39"},"quality":1}"
I created a class.
public class OrderR
{
public Guid ID { get; set; }
public Guid orrderItems { get; set; }
public string CODE { get; set; }
public string NAME { get; set; }
public int PRICE { get; set; }
public string CATEGORY { get; set; }
}
I am trying to get an array.
[HttpPost]
public async Task<IActionResult> AddOrder(OrderR[] orderR)
But get null.
What am I doing wrong?
How is it correct?
Create new class:
public class Order
{
public OrderR Product { get; set; }
public int Quality { get; set; }
}
and change your action to this:
[HttpPost]
public async Task<IActionResult> AddOrder(Order[] orders)
{
.... your code
}
it was tested in Postman using this data:
[
{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-08d8db1aac26","code":"666666","name":"test1","price":6,"category":"test6","orrderItems":"320d57eb-3333-45d2-f497-08d8d66a0d39"},"quality":1},
{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-08d8db1aac26","code":"666666","name":"test2","price":6,"category":"test6","orrderItems":"320d57eb-3333-45d2-f497-08d8d66a0d39"},"quality":1},
{"product":{"id":"72ae28f2-4ad3-4e97-5a7b-08d8db1aac26","code":"666666","name":"test3","price":6,"category":"test6","orrderItems":"320d57eb-3333-45d2-f497-08d8d66a0d39"},"quality":1}
]
and everything works fine. If you want to test it in Postman too, add [FromBody] to the action input parameter:
[HttpPost]
public async Task<IActionResult> AddOrder([FromBody] Order[] orders)
{
return Ok(orders);
}

Why Entity Framework replaces provided value with a new incremental value

I'm trying to work my way through a Dot Net Core MVC project, but I am facing a problem I couldn't solve.
And honestly, I didn't know what to search for.
The project is a simple vehicle registry,
Each vehicle has a Make, a Model, a some Features.
Here are the domain models:
public class Make
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Model> Models { get; set; }
public Make()
{
Models=new Collection<Model>();
}
}
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
public Make Make { get; set; }
public int MakeId { get; set; }
public Model()
{
Make=new Make();
}
}
public class Feature
{
public int Id { get; set; }
public string Name { get; set; }
}
[Table(name:"VehicleFeatures")]
public class VehicleFeature
{
public int VehicleId { get; set; }
public int FeatureId { get; set; }
public Feature Feature { get; set; }
public Vehicle Vehicle { get; set; }
public VehicleFeature()
{
Feature=new Feature();
Vehicle=new Vehicle();
}
}
public class Vehicle
{
public int Id { get; set; }
public Model Model { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ModelId { get; set; }
public ICollection<VehicleFeature> VehicleFeatures { get; set; }
public string ContactName { get; set; }
public string ContactPhone { get; set; }
public string ContactEmail { get; set; }
public DateTime LastUpdate { get; set; }
public bool IsRegistered { get; set; }
public Vehicle()
{
Model=new Model();
VehicleFeatures=new Collection<VehicleFeature>();
}
}
The problem is that when I send the following request to the corresponding controller, EF is replacing the provided value with a new incremental value.
The request I send:
{
"ModelId":10,
"VehicleFeatures":[
{"featureId":45},
{"featureId":46}
],
"ContactName":"Alice",
"ContactPhone":"1234",
"ContactEmail":"Alice#local",
"LastUpdate":"1980-01-01",
"IsRegistered":true
}
And this is what happens:
The controller receives correct values,
Correct values are added to the context,
And then suddenly all hell breaks loose.
This is the controller code:
[HttpPost]
public async Task<IActionResult> CreateVehicle([FromBody] Vehicle v)
{
context.Vehicles.Add(v);
await context.SaveChangesAsync();
return Ok(v.ModelId);
}
What am I missing here?

How to pass object in method to call service API in ASP.NET Boilerplate?

I have defined a method defined in AppService file, Signature of method is public PagedResultDto<FetchData> GetSearchData(FetchDataInput searchInput). I'm calling this method from Angular code, but service-proxoes.ts file has generated method in which I need to pass all the parameters one by one.
public class FetchDataInput: PagedAndSortedInputDto, IShouldNormalize
{
public int DataLevel { get; set; }
public int DataType { get; set; }
public string DataCode { get; set; }
public string DescLong { get; set; }
public string LanguageCode { get; set; }
public string DataParent { get; set; }
public void Normalize()
{
if (string.IsNullOrEmpty(Sorting))
{
Sorting = "DataCode";
}
}
}
Service-Proxies.ts file:
getSearchData(dataLevel: number, dataType: number, dataCode: string, descLong: string, languageCode: string, dataParent: string, sorting: string, maxResultCount: number, skipCount: number): Observable<PagedResultDtoOfFetchData> {
So I have to call the getSearchData method by the following way.
this._dataService.getSearchData(AppConsts.dataLevelType, undefined, undefined,
undefined, this.currentLanguage.name, undefined, undefined, undefined, undefined).subscribe((result) => {
//result.items;
});
So I have to pass all the parameters, but if let's say there are 100 parameters, it will be error prone and not good programming style. So it has to take a class object that's it. So is there any way to do the this?
You can create a object to store those parametter like this:
public class FetchDataInput: PagedAndSortedInputDto, IShouldNormalize
{
public SearchModel searchModel{get; set;}
public void Normalize()
{
if (string.IsNullOrEmpty(Sorting))
{
Sorting = "DataCode";
}
}
}
public class SearchModel
{
public int DataLevel { get; set; }
public int DataType { get; set; }
public string DataCode { get; set; }
public string DescLong { get; set; }
public string LanguageCode { get; set; }
public string DataParent { get; set; }
}
...And in the getSearchData, tried to serialize the model and pass it to your api:
_$SearchModelForm= _modalManager.getModal().find('form[name=SearchForm]');
var searchModel = _$SearchModelForm.serializeFormToObject();
this._dataService.getSearchData(searchModel);

Posting a complex object through ajax along with other simple types

I know that this question has been asked like a hundred times, but I can't figure it out.
I have an ajax call like
function saveBox()
{
var postModel = createBoxPostModel();
showLoader();
$.ajax({
async: true,
type: 'post',
url: '#(Url.BuildAction<IncomingGoodsVerificationController>(x => x.SaveWorkUnitForBox(null, null, null)))',
data: { jsonPostModel: postModel, boxItemKey: boxItemKey, itemKey: itemKey },
success: function (data, status) {
...
},
error: function (jqXHR, textStatus, errorThrown) {
hideLoader();
displayErrorMessagePopup('Error in saving box! ', errorThrown, 'error-msgs');
}
});
}
and the controller method is like
[HttpPost]
public JsonResult SaveWorkUnitForBox(NewWorkUnitBoxModel postModel, string boxItemKey, string itemKey)
{
....
}
The NewWorkUnitBoxModel is
public class NewWorkUnitBoxModel
{
public NewWorkUnitBoxModel();
public string AlternativeWorkUnitNumer { get; set; }
public string Barcode { get; set; }
public int ChooseType { get; set; }
public decimal? GrossWeight { get; set; }
public long IdCompany { get; set; }
public long? IdPackagingType { get; set; }
public long? IdWorkUnitSubType { get; set; }
public decimal? NetWeight { get; set; }
public string Tone { get; set; }
public decimal? Volume { get; set; }
public long? WorkUnitNumber2 { get; set; }
}
and yet when the controller action is called is either null or the object has no value for each of its properties.
I tried several ways:
data: { jsonPostModel: postModel, boxItemKey: boxItemKey, itemKey: itemKey }
data: { jsonPostModel: JSON.stringify(postModel), boxItemKey: boxItemKey, itemKey: itemKey }
Putting all action parameters inside a request class
None of these worked. Client-side the model is loaded correctly, and by using ModelBinders I also looked inside the HtmlRequest and data had arrived on the server. I only solved with changing the type to a string and deserialize it inside the action.
How can I make it automatically deserialize the model?

Post a Javascript array not working with DefaultModelBinder?

Code
I can not send an array of javascript objects to the server.
ModelBinder standard does not recognize the format.
On my server I have classes:
public class PessoaViewModel
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
public string Nome { get; set; }
public string Tipo { get; set; }
public string CPF { get; set; }
public ICollection<TelefoneViewModel> Telefones { get; set; }
public ICollection<EnderecoViewModel> Enderecos { get; set; }
public ICollection<EmailViewModel> Emails { get; set; }
public PessoaViewModel Conjuge { get; set; }
}
public class TelefoneViewModel
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[AdditionalMetadata("class", "span2")]
[AdditionalMetadata("placeholder", "Tipo")]
public string Tipo { get; set; }
[DataType(DataType.PhoneNumber)]
[AdditionalMetadata("class", "span2")]
public string Numero { get; set; }
[HiddenInput(DisplayValue = false)]
public int Ordem { get; set; }
}
I'm not listing the rest of the class because it is not yet used in the code!
My javascript
$.ajax
url: $(form).attr("action")
type: "POST"
error: (err, errType, errMessage) ->
console.error a.statusText
cache: false
data: ko.mapping.toJS(#, ignoreFunctionsMapping)
success: (data, txtStatus) -> console.log "OK!!?? On server maybe not!"
Server result
Full image: http://i.stack.imgur.com/NeIm1.jpg
Question
As you can see, the post is being done and the values ​​are correct.
But asp.net mvc does not fill correctly the Telefones object!
What am I doing wrong?
Your problem is because you are missing a ".", it should have the format:
Telefones[0].Id: 1
Telefones[0].Ordem: bli

Resources