So I have been learning some .net core and I am building an API with it. Normally I would work with angular and send requests there.
I have the following angular snippet:
//The data I need to send.
$scope.PersonalInfo = {
firstName: '',
lastName: '',
companyName: '',
email: '',
password: '',
confirmPassword: '',
imageLink: ''
};
Then there's the backend model for the same data:
public class UserProfileModel
{
public string userID { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string companyName { get; set; }
public string email { get; set; }
public string password { get; set; }
public string confirmPassword { get; set; }
public string imageLink { get; set; }
}
And finally the method that should send it:
$scope.UpdateProfile = function () {
var profile = JSON.stringify($scope.PersonalInfo);
$http.post('/api/Profile/Users', profile).then(function (response) {
debugger;
$log.log(profile);
$log.log(response);
});
};
No matter how many changes I have done, (send the data as a stringified JSON, or send the scoped object), when the request hits the controller, I end up with this:
$scope.PersonalInfo is full of data before the request is sent.
Any help is very appreciated. Thanks in advance.
You need to mention [FromBody] attribute in your post call. Like So,
[HttpPost]
[Route("api/bar/users")]
public IActionResult Users([FromBody]UserProfileViewModel profile)
{
return Json(new { Data = profile });
}
That should do it.
The necessity to use the FromBody attribute is so that the framework can use the correct input formatter to model bind. The default formatter used, for example, with content type application/json is the JSON formatter based on Json.Net
Detailed information at: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
Related
I have complex form with strings, files. And I'm adding to this form some JSON/object.In controller I can't handle my added object(Product) you can see it below.
Models
Model 1. MyData
public string SomeThing { get; set; }
public IEnumerable<Product> Products { get; set; }
public IEnumerable<HttpPostedFileBase> Files { get; set; }
Model 2. Product
public int Id { get; set; }
public int Count { get; set; }
Controller
[System.Web.Http.HttpPost]
public HttpStatusCodeResult GetData(MyData data) <== SomeThing-OK.Files-OK,Products-Products[0]
{
//logic
}
JS. I'm using Vue fetch API but it isn't a deal.The same thinks occurrence when I use JQuery.
let form = new FormData(this.$refs.myForm);
form.append('Products', [{ 'Id': 1, 'Count': 2 }]) <== In controller I always get Products[0] =(
fetch('/GetData', {
method: 'post',
body: form
})
})
I'm totally confused. I don't want refuse using FormData(). I can easily handle files with it. But my controller doesn't see any complex(Products) object if I don't use JSON(stringify). I will be grateful for any advice.
I'm posting some form data through ajax to my server. I also grab a some Id's from an array in memory and add it to the form data:
var postData = $('#frmMoveToNewPackage').serializeArray();
postData.push({
name: 'DocumentIds',
value: _checkboxList.getAllChecked()
});
$.post('#Url.Action("MoveToNewPackage")', postData);
My model is this:
public class MoveToNewPackageModel
{
[Required]
public int OldPackageID { get; set; }
[Required]
public Package NewPackage { get; set; }
public List<string> DocumentIds { get; set; }
}
This works. However technically the list of DocumentIds should be a List<int>. If I change the type in my modal, and change the post data:
postData.push({
name: 'DocumentIds',
value: _checkboxList.getAllChecked().map(function(item) { return parseInt(item);});
});
Then my DocumentIds is an empty (but not null) list of ints. I've looked at the data being posted and it's a valid int array.
EDIT: Above is wrong. It was not correctly binding the list of strings. It was just jamming everything into the first item of the string array.
I am having trouble sending a complex object to my SignalR hub. My JavaScript object matches exactly to my C# object, so I would expect everything to work. However, I am unable to hit my UpdateEmployee method. I have other methods in my hub that work just fine with simple types. Here is what I currently have implemented -
SignalR Hub
public void UpdateEmployee(int userId, Employee employee)
{
// Update employee
}
Where Employee is defined as
public class Employee: Persistable
{
[DataMember]
public DateTime? DateOfBirth { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
Which just simply inherits Persistable
[DataContract]
public class Persistable
{
[DataMember(Name = "id")]
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
}
I am trying to hit that method from my SignalR JavaScript client
$.connection.myHub.server.updateEmployee(userId, employee);
Where my employee object in JavaScript looks like
{ Id: 1, FirstName: "Test", LastName: "One", DateOfBirth: "01012001" }
Is there anything I am doing wrong here?
Have you tried it without the DateOfBirth value?
Perhaps it isn't able to bind your value 01012001 to the nullable DateTime? I have a feeling it has to be either NULL or a bindable value, else the binding will actually fail.
I have a game object in client side JavaScript that looks like this right before being sent to the server:
Here it is server side a second later, note all the properties are filled, and the Questions list is populated with the correct number of question, however the properties of each question are null, whereas on the client side they had the correct values.
Here is the code for the models:
public class Game
{
public Game()
{
Questions = new List<Question>(5);
}
public int GameID { get; set; }
public Guid UserID { get; set; }
public Guid CurrentGameID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IEnumerable<Question> Questions { get; set; }
}
public class Question
{
public int ID { get; set; }
public string Text { get; set; }
public IEnumerable<int> Answers { get; set; }
public int SelectedAnswer { get; set; }
}
And here is how I send the object back to the server:
// Send completed game back to server
$.post("Games/CompleteGame", currentGame, function (results)
{
// display results to user
}
Based on Ek0nomik's comment asking about the content-type, I rewrote my ajax call to set contentType to json:
$.ajax(
{
url: "Games/CompleteGame",
type: "POST",
data: JSON.stringify(currentGame),
contentType: "application/json",
success: function (results)
{
// show results to user...
}
As it turns out, this was all it needed to make it work.
Not sure if it's just the time of day, lack of coffee or over indulgence of sugar from last night. Besides that I'm trying to get this working. I do not want to change / modify / add a new web service method.
I have an asmx web service:
public UserLogin Login(UserLogin p_objUserLogin)
{
}
I need to hook a JQuery ajax call up to that. The UserLogin object is not that complex:
public class UserLogin
{
public UserLogin();
public string Privileges { get; set; }
public string ClientCodeID { get; set; }
public UserDetails User { get; set; }
public string UserLoginMessage { get; set; }
public bool Valid { get; set; }
}
The UserDetails object is quite large, and includes a lot more data. (Hopefully I don't need to build the entire object tree to get this to work).
public class UserDetails
{
public string CellPhone { get; set; }
public string Email { get; set; }
public string EncryptedPassword { get; set; }
public string FirstName { get; set; }
public string FullName { get; }
public string Initials { get; set;
public bool InService { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public byte[] Signature { get; set; }
public string SimCard { get; set; }
public int UserID { get; set; }
public string UserName { get; set; }
public SecurityRole UserSecurityRole { get; set; }
public Workgroup UserWorkgroup { get; set; }
}
The script I'm playing around with:
function CallService() {
var p_objUserLogin = {};
p_objUserLogin['ClientCodeID'] = "Test";
var DTO = { 'p_objUserLogin': p_objUserLogin };
$.ajax({
type: "POST",
url: "UtilityServices2006.asmx/Login",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (msg) {
alert(msg);
},
error: function (req, status, error) {
alert(req + ", " + status + ", " + error);
},
complete: function (req, status) {
alert(req + ", " + status);
}
});
}
Any help would be quite amazing.
Ensure your webservice class and method are decorated to handle incoming ajax/json requests:
[ScriptService]
public class MyService: WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public UserLogin Login(UserLogin p_objUserLogin)
{
}
}
I'm not familiar with the notation you're using to configure your payload object (p_objUserLogin['ClientCodeID'] = "Test";). I've usually used slightly different notation:
p_objUserLogin.ClientCodeID = 'Test';
However, that might be a red herring - I'm not a JS-objects expert, so your notation may be perfectly valid.
Finally, I'm not sure if JS will automatically convert your object to JSON (var DTO = { 'p_objUserLogin': p_objUserLogin };). I use the json2 library to explicitly serialize JS objects to JSON:
var DTO = { 'p_objUserLogin': JSON.stringify(p_objUserLogin) };
Hope this helps you nail down the issue.