gpt4 book ai didi

angularjs - Angular JS MVC Web API 模型/参数未绑定(bind) .NET Core

转载 作者:行者123 更新时间:2023-12-04 15:31:50 25 4
gpt4 key购买 nike

我正在使用带有 TypeScript 和 ASP.NET Core MVC/API 的 Angular JS。

我有一个 apiService处理所有POSTGET对服务器的请求,如下所示:

module TBApp {

export class apiService {

static $inject = ['$http', 'notificationService'];

constructor(private $http, private notificationService: notificationService) {

}

get(url, config, success, failure) {

return this.$http.get(url, config)

.then(result => { this.handleResponse(result, success); }, result => { this.handleError(result, failure) });
}

post(url, data, success, failure) {

return this.$http.post(url,data)
.then(result => { this.handleResponse(result, success); }, result => { this.handleError(result, failure) });
}

handleResponse(result, success) {

alert('success');
success(result);

}

handleError(result, failure) {

if (result.status === '401') {

this.notificationService.displayError('Authentication required.');
//this.$rootScope.previousState = this.$location.path();
//this.$location.path('/login');

}
else if (failure !== null) {
failure(result);
}
}
}
}

现在,当我发送此请求时:
    onCompanyChanged(selectedCompany, model, companyName) {

this.apiService.post('/api/Dashboard/GetAssetListByCompany', { companyId: selectedCompany.id },

response => {

this.assetListViewModel = response.data.data;


}, response => {
this.notificationService.displayError(response.data.message);
});
}

它不绑定(bind) companyId在 Controller 中

这是 Controller :
   [Route("api/[controller]")]
public class DashboardController : BaseController
{
[HttpPost]
[Route("GetAssetListByCompany")]
public IActionResult GetAssetListByCompany([FromBody]int companyId)
{
return CreateJsonResult(() =>
{
if (companyId == 0) { return new xPTJsonResult(null, xPTStatusCodesEnum.Success, "Company Id is 0"); }

//var treeModel = _dashboardProvider.GetTreeModelByCompany(companyId, userModel);

return new xPTJsonResult(null, xPTStatusCodesEnum.Success, "Loaded assets successfully");

});
}

}

即使当我在浏览器中检查请求时,显示 companyId 在有效负载中。

enter image description here

NOTE: The same function works when I post a ViewModel



编辑

在上述场景中,我只将一个参数传递给 Controller ​​,但在某些情况下,我希望能够在不使用 ViewModel 的情况下传递 2 个或 3 个参数。

例如
public IActionResult GetAssetListByCompany([FromBody]int companyId, [FromBody]int assetId)
{....

或者
public IActionResult GetAssetListByCompany([FromBody]int companyId, [FromBody]int assetId, [FromBody]bool canEdit = false)
{.....

然后在客户端我可以这样做:
this.apiService.post('/api/Dashboard/GetAssetListByCompany', { companyId: selectedCompany.id, assetId: 123 }.....

或者
this.apiService.post('/api/Dashboard/GetAssetListByCompany', { companyId: selectedCompany.id, canEdit: true, assetId: 22 }....

最佳答案

此处最好的方法是遵循 HTTP 指南并将您的操作从 POST 更改为 GET,因为您没有修改任何数据。这非常简单,并且仍然能够使用 URI 随请求一起发送数据。

MVC 变化

Model Binding对于各种选项,这里最好的方法是基于查询字符串进行绑定(bind),因为您只需要一个原始类型。如果您有一个原始类型数组,您仍然可以绑定(bind)到查询字符串,查询字符串变量名称将为每个值重复一次。

因此,我们所做的唯一更改是指定参数来自 Query 字符串,并且它与 Http Get 请求而不是 Post 相关联。

[Route("api/[controller]")]
public class DashboardController : BaseController
{
[HttpGet] // change to HttpGet
[Route("GetAssetListByCompany")]
public IActionResult GetAssetListByCompany([FromQuery]int companyId) // use FromQuery
{
return CreateJsonResult(() =>
{
if (companyId == 0) { return new xPTJsonResult(null, xPTStatusCodesEnum.Success, "Company Id is 0"); }

//var treeModel = _dashboardProvider.GetTreeModelByCompany(companyId, userModel);

return new xPTJsonResult(null, xPTStatusCodesEnum.Success, "Loaded assets successfully");

});
}
}

AngularJS 的变化

我们扩展了 apiService 以允许使用 HttpGet 为调用传递数据。这可以使用 params on the $http call 来完成。 ,它将根据传入的数据动态创建URL,使用名称作为查询字符串值名称,值作为值部分。
export class apiService {
/* all other code is left as is, just change the get method to also accept data via the params. If null is passed in then it is ignored. */
get(url, config, data, success, failure) {
return this.$http({
url: url,
config: config,
params: data,
method: "GET"
})
.then(result => { this.handleResponse(result, success); }, result => { this.handleError(result, failure) });
}
}

在通话中,我们只需要从 post 更改至 get它应该可以工作。
// only change from post to get
onCompanyChanged(selectedCompany, model, companyName) {
this.apiService.get('/api/Dashboard/GetAssetListByCompany', { companyId: selectedCompany.id },
response => {
this.assetListViewModel = response.data.data;
}, response => {
this.notificationService.displayError(response.data.message);
});
}

编辑 - 这是灵活的

更重要的一点是,这种设计在 Angular 方面很灵活。如果您扩展您的 MVC 操作或具有采用其他参数的各种操作,则无需实现任何其他更改即可工作。例子:
[HttpGet]
[Route("GetSomethingElseFromServer")]
public IActionResult GetSomethingElseFromServer([FromQuery]int companyId, [FromQuery]string assetName, [FromQuery]string companyModelNumber) // use FromQuery

对您的 Angular api 的调用将是
this.apiService.get('/api/Dashboard/GetSomethingElseFromServer', { companyId: companyId, assetName: somePassedInAssetNameVar, companyModelNumber: somePassedInModelNumber }

编辑 - 您还可以发送数组

要回答有关如何将多个原始类型作为数组发送的问题,您可以这样做。同样,这假定它不是您要发送的复杂类型,而是例如公司 ID 列表。

c# 代码
[HttpGet]
[Route("GetAssetListByCompany")]
public IActionResult GetAssetListByCompany([FromQuery]int[] companyIds) // use an array of int ie. int[]. i changed the variable name to make it clear there can be more than 1

Angular 调用,注意不需要更改服务
onCompanyChanged(selectedCompany, model, companyName) {
this.apiService.get('/api/Dashboard/GetAssetListByCompany', { "companyIds[]": [id1, id2, id3] }, // note the name is now enclosed in quotes, made plural, and includes []. The value is an array
response => {
this.assetListViewModel = response.data.data;
}, response => {
this.notificationService.displayError(response.data.message);
});
}

编辑 - 如果你仍然想发布

您目前只发送一个原始字段,因此 MVC 框架在 POST 中无法正确反序列化。您需要将参数包装在 View 模型中,将其作为查询字符串部分发送,或将其作为表单字段值发送。这是带有查询字符串部分的 POST,它工作得很好。

选项1

将其附加到 URL
[HttpPost] // change to HttpGet
[Route("GetAssetListByCompany")]
public IActionResult GetAssetListByCompany([FromQuery] int companyId) // use FromQuery

Angular 调用
this.apiService.post('/api/Dashboard/GetAssetListByCompany/?companyId=' + selectedCompany.id + , null, // the rest of the code remains unchanged so I did not include it

选项 2

扩展 apiService 以获取 params 对象,以便它可以构建您的查询。无论哪种方式,您都会遇到调用者必须对正在进行的 http 调用有所了解的情况。
this.apiService.post('/api/Dashboard/GetAssetListByCompany', null, {companyId: selectedCompany.id}, null, // the rest of the code remains unchanged so I did not include it

post(url, config, data, params, success, failure) {
return this.$http({
url: url,
config: config,
data: data,
params: params,
method: "POST"
})
.then(result => { this.handleResponse(result, success); }, result => { this.handleError(result, failure) });
}

选项 3

更新您的 View 模型以采用复杂类型,这不需要更改您的 Angular 代码。
public class ListByCompanyModel {
public int CompanyId {get;set;}
}

[HttpPost] // change to HttpGet
[Route("GetAssetListByCompany")]
public IActionResult GetAssetListByCompany([FromBody] ListByCompanyModel model) // use FromQuery

关于angularjs - Angular JS MVC Web API 模型/参数未绑定(bind) .NET Core,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39124248/

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