gpt4 book ai didi

javascript - 将复杂的Javascript对象传递给ASP.NET Web服务

转载 作者:行者123 更新时间:2023-11-29 19:34:45 24 4
gpt4 key购买 nike

我正在使用jQuery AJAX函数将复杂的JavaScript对象传递给ASP.NET Web服务中的Web方法。我遵循了本文中的建议(以及其他建议):

Using Complex Types to Make Calling Services Less Complex

现在,我能够从客户端到浏览器以及从浏览器到客户端传递对象。但是,我遇到了一个我无法解决的问题。从客户端到浏览器传递复杂的对象时,数据在旅途中会以某种方式“丢失”。我在传递给Web服务的JSON字符串中存在该字符串,但是当ASP.NET AJAX将JSON字符串转换为该对象的新实例并将其传递给service方法时,就会丢失某些部分。

复杂类型是一个Meal对象,由几个属性,一顿用于膳食的食谱和一组单个Food项目组成。数组中的每个Recipe对象都包含一些属性和食品的“字典”(作为成分),食品作为键,其各自的数量作为值。 Food对象仅具有属性。看一下JavaScript中各种对象的结构:

function Meal() {

this.MealNumber;
this.MealName;
this.MealType;
this.Ratio;
this.DailyCalorieTarget;
this.Recipes = [];
this.Foods = []
}

function Recipe() {

this.RecipeNumber;
this.RecipeName;
this.RecipeInstructions;
this.Foods = [];
}

function Food() {

this.FoodNumber;
this.FoodName;
this.CaloriesPerGram;
this.FatPerGram;
this.CarbsPerGram;
this.DietaryFiberPerGram;
this.ProteinPerGram;
this.Category;
}


现在,检查Web服务中的相应对象:

Meal:

int MealNumber;
string MealName;
string MealType;
float Ratio;
int DailyCalorieTarget;

List<Recipe> Recipes;
List<KeyValuePair<Food, float>> Foods;

Recipe:

int RecipeNumber;
string RecipeName;
string RecipeInstructions;
List<KeyValuePair<Food, float>> Foods;

Food:

int FoodNumber;
string FoodName;
float CaloriesPerGram;
float FatPerGram;
float CarbsPerGram;
float DietaryFiberPerGram;
float ProteinPerGram;
string Category;


如您所见,属性是相同的。你们中的有些人可能会问为什么我在服务器端而不是Dictionary对象上使用KeyValuePairs列表。你们中的其他人已经知道Dictionary对象不会序列化为JSON字符串,而KeyValuePairs列表将会序列化。

现在,解决问题:我的Web服务中有两个Web方法-getMealData()和postMealData()。这是我出于调试目的所做的事情:


当我单击客户端中的“获取膳食数据”按钮时,我正在使用jQuery向getMealData()方法发出AJAX请求。 getMealData()方法使用一些Recipe和Food数据填充Meal对象,使用JavaScriptSerializer.Serializer方法序列化Meal,然后将JSON字符串发送回客户端,在此JSON.parse方法将字符串解析为进餐对象。
之后,单击“发送膳食数据”按钮,然后使用以下脚本通过JSON.stringify我刚从getMealData()方法创建的EXACT SAME对象:

函数postMealData(){

var DTO = { 'meal': meal }

$.ajax({
type: "POST",
url: "KetoCompanionService.asmx/postMealObject",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {

$('#returnedData').html(msg.d);

},

error: function (msg) {

$('#returnedData').html(msg.responseText);

}
});


}


在获取膳食数据并将其发送回服务器之间,我什么也没做。这里要做的就是从服务器获取JSON数据并将其解析为JavaScript对象。我要对EXACT SAME对象进行字符串化处理,然后将其发送回服务器。但是,我在服务器端得到的与我发送的不匹配。

我从服务器端的getMealData方法获取的JSON字符串:

{"MealNumber":1,"MealName":"Cheese Pizza, Strawberries, and Cream","MealType":"Dinner","Ratio":2.25,"DailyCalorieTarget":1600,"Recipes":[{"RecipeNumber":10,"RecipeName":"Cheese Pizza","RecipeInstructions":"Just fix the damned thing...","Foods":[{"Key":{"FoodNumber":1,"FoodName":"Eggs","CaloriesPerGram":1.432,"FatPerGram":0.823,"CarbsPerGram":0.234,"DietaryFiberPerGram":0,"ProteinPerGram":0.432,"Category":"Protein"},"Value":20},{"Key":{"FoodNumber":2,"FoodName":"Nuts","CaloriesPerGram":2.432,"FatPerGram":1.823,"CarbsPerGram":1.234,"DietaryFiberPerGram":1,"ProteinPerGram":1.432,"Category":"Protein"},"Value":10}]}],"Foods":[{"Key":{"FoodNumber":3,"FoodName":"Strawberries","CaloriesPerGram":0.332,"FatPerGram":0.723,"CarbsPerGram":0.034,"DietaryFiberPerGram":0.2,"ProteinPerGram":0.232,"Category":"Carbs"},"Value":120}]}


在ASP.NET AJAX将其从postMealData方法获取的字符串转换为服务器端的Meal对象之后,它看起来像这样:

{"MealNumber":1,"MealName":"Cheese Pizza, Strawberries, and Cream","MealType":"Dinner","Ratio":2.25,"DailyCalorieTarget":1600,"Recipes":[],"Foods":[]}


简而言之,“配方”和“食物”数组现在为空。那数据怎么了?自然,我在客户端的传出数据和传入的Web方法中设置断点。该对象离开时会很好,但是到达时会丢失数组数据。

我非常谦虚地承认我在进行复杂的字符串化时可能犯一个愚蠢的错误。但是,我没有进行这种分类-ASP.NET和JavaScript进行了。我所做的就是在它们之间来回传递字符串。

我缺少有关列表序列化的东西吗?

H-E-双曲棍球棒会在这里发生什么?我正在拔头发!

感谢您抽出宝贵的时间阅读这么长的文章。

杰里米

编辑添加:

客户端getMealData()代码:

function getMealData() {
$.ajax({
type: "POST",
url: "KetoCompanionService.asmx/getMealObject",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {

meal = JSON.parse(msg.d);

// Insert the returned HTML into the <div>.
$('#returnedData').html(msg.d);
},
error: function (msg) {

$('#returnedData').html(msg.responseText);
}
});
}


服务器端getMealDataMethod:

[WebMethod]
[ScriptMethod(UseHttpGet=false, ResponseFormat = ResponseFormat.Json)]
public string getMealObject() {

JavaScriptSerializer js = new JavaScriptSerializer();

_meal = new Meal();
_meal.MealNumber = 1;
_meal.MealName = "Cheese Pizza, Strawberries, and Cream";
_meal.MealType = "Dinner";
_meal.Ratio = 2.25f;
_meal.DailyCalorieTarget = 1600;

Recipe _recipe1 = new Recipe();
_recipe1.RecipeNumber = 10;
_recipe1.RecipeName = "Cheese Pizza";
_recipe1.RecipeInstructions = "Just fix the damned thing...";

Food _recipe1Food1 = new Food();
_recipe1Food1.FoodNumber = 1;
_recipe1Food1.FoodName = "Eggs";
_recipe1Food1.CaloriesPerGram = 1.432f;
_recipe1Food1.FatPerGram = 0.823f;
_recipe1Food1.CarbsPerGram = 0.234f;
_recipe1Food1.DietaryFiberPerGram = 0.0f;
_recipe1Food1.ProteinPerGram = 0.432f;
_recipe1Food1.Category = "Protein";

KeyValuePair<Food, float> _kvp1 = new KeyValuePair<Food, float>(_recipe1Food1, 20.0f);
_recipe1.Foods.Add(_kvp1);

Food _recipe1Food2 = new Food();
_recipe1Food2.FoodNumber = 2;
_recipe1Food2.FoodName = "Nuts";
_recipe1Food2.CaloriesPerGram = 2.432f;
_recipe1Food2.FatPerGram = 1.823f;
_recipe1Food2.CarbsPerGram = 1.234f;
_recipe1Food2.DietaryFiberPerGram = 1.0f;
_recipe1Food2.ProteinPerGram = 1.432f;
_recipe1Food2.Category = "Protein";

KeyValuePair<Food, float> _kvp2 = new KeyValuePair<Food, float>(_recipe1Food2, 10.0f);
_recipe1.Foods.Add(_kvp2);

_meal.Recipes.Add(_recipe1);

Food _mealFood1 = new Food();
_mealFood1.FoodNumber = 3;
_mealFood1.FoodName = "Strawberries";
_mealFood1.CaloriesPerGram = 0.332f;
_mealFood1.FatPerGram = 0.723f;
_mealFood1.CarbsPerGram = 0.034f;
_mealFood1.DietaryFiberPerGram = 0.2f;
_mealFood1.ProteinPerGram = 0.232f;
_mealFood1.Category = "Carbs";

KeyValuePair<Food, float> _kvp3 = new KeyValuePair<Food, float>(_mealFood1, 120.0f);
_meal.Foods.Add(_kvp3);

string returnString = js.Serialize(_meal);

return returnString;
}


更新:

在我的getMealData()JavaScript函数中,我没有存储从服务器返回的JSON数据并将其存储在餐对象中,而是简单地存储了原始字符串。

然后,在我的postMealData()JavaScript函数中,不是对将要创建的餐对象进行字符串化,而是使用原始文本进行了自己的字符串化:

var DTO = "{ \"meal\" : " + meal + "}";


然后,我在AJAX请求中将该DTO字符串作为我的 data:属性发送。

我得到了相同的结果。好像ASP.NET使用了不同的算法来序列化膳食对象,而不是使用了反序列化算法。当我将其发送回时,甚至ASP.NET发送给我的原始JSON字符串也不起作用。

最佳答案

解决方案-第1部分

我发现了为什么我的Recipe和Foods数组为空-我为ASP.NET中的每个Meal,Recipe和Food类创建的每个公共属性都具有getter和setter -除了List。我忽略了在该属性中放置一个setter,使其成为只读。因此,Web方法无权访问这些属性以进行设置。

但是,我还没有走出困境。即使我发现了丢失的数据,我的Foods数组也在服务器端出现{Key:null,Value:0},即使我正在发送食品数据键值对。

解决方案-第2部分

我已经解决了这个问题。

显然,当涉及到KeyValuePair对象列表时,ASP.NET AJAX存在反序列化JSON的问题。

因此,我没有使用类型List<KeyValuePair<Food, float>>来存储我的单个食品,而是创建了自己的类,并使用属性FoodWithAmountFoodItem调用了Amount,而不是使用以下类:List<KeyValuePair<Food, float>>正在使用此:List<FoodWithAmount>。一旦实现了此更改,服务器端就可以将JSON字符串完美地转换为餐对象。

public class FoodWithAmount
{
Food _foodItem;
float _amount;

public Food FoodItem
{
get { return _foodItem; }
set { _foodItem = value; }
}

public float Amount
{
get { return _amount; }
set { _amount = value; }
}

//Parameterless constructor is necessary for serialization
public FoodWithAmount()
{
}

public FoodWithAmount(Food foodItem, float amount)
{
_foodItem = foodItem;
_amount = amount;
}
}


在过去的几周中,我在学习JavaScript,ASP.NET,jQuery,HTML和CSS时遇到的所有障碍中,这个问题比其他任何问题都花费了我更多的时间和精力。

我希望我的苦难使别人的旅途更轻松。

编码愉快!!

关于javascript - 将复杂的Javascript对象传递给ASP.NET Web服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25656787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com