angularjs – Angular JS MVC Web API模型/参数不绑定.NET Core
我正在使用带有TypeScript和ASP.NET Core MVC / API的Angular JS.
我有一个apiService来处理对服务器的所有POST和GET请求,如下所示: 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,failure) { return this.$http.post(url,data) .then(result => { this.handleResponse(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); }); } 它没有绑定控制器中的companyId 这是控制器: [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,"Loaded assets successfully"); }); } } 即使我在浏览器中检查了请求,也表明companyId在Payload中.
编辑 在上面的场景中,我只将一个参数传递给控制器??,但在某些情况下,我希望能够在不使用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',canEdit: true,assetId: 22 }.... 解决方法
这里最好的方法是遵循HTTP准则并将操作从POST更改为GET,因为您不修改任何数据.这很简单,仍然可以使用URI通过您的请求发送数据.
MVC改变了 有关各种选项,请参阅Model Binding,此处的最佳方法是基于查询字符串进行绑定,因为您只需要一个基本类型.如果您有一个基本类型数组仍然可以绑定到查询字符串,则查询字符串变量名称将为每个值重复一次. 因此,我们所做的唯一更改是指定参数来自查询字符串,并且它与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,"Company Id is 0"); } //var treeModel = _dashboardProvider.GetTreeModelByCompany(companyId,userModel); return new xPTJsonResult(null,"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,failure) { return this.$http({ url: url,config: config,params: data,method: "GET" }) .then(result => { this.handleResponse(result,failure) }); } } 在通话中我们只需要从post更改为get,它应该可以工作. // only change from post to get onCompanyChanged(selectedCompany,companyName) { this.apiService.get('/api/Dashboard/GetAssetListByCompany',response => { this.assetListViewModel = response.data.data; },response => { this.notificationService.displayError(response.data.message); }); } 编辑 – 这很灵活 更重要的是,这种设计在角度方面是灵活的.如果您扩展MVC操作或具有采取其他参数的各种操作,则无需执行任何其他更改即可运行.例: [HttpGet] [Route("GetSomethingElseFromServer")] public IActionResult GetSomethingElseFromServer([FromQuery]int companyId,[FromQuery]string assetName,[FromQuery]string companyModelNumber) // use FromQuery 对你的角度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,{ "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); }); } 编辑 – 如果你想要POST 您目前只发送一个原始字段,因此POST中的MVC框架无法正确反序列化.您需要将参数包装在视图模型中,将其作为查询字符串部分发送,或将其作为表单字段值发送.这是带有查询字符串部分的POST,它可以正常工作. 选项1 将其附加到URL [HttpPost] // change to HttpGet [Route("GetAssetListByCompany")] public IActionResult GetAssetListByCompany([FromQuery] int companyId) // use FromQuery 角度呼叫 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',{companyId: selectedCompany.id},// the rest of the code remains unchanged so I did not include it post(url,params,failure) { return this.$http({ url: url,data: data,params: params,method: "POST" }) .then(result => { this.handleResponse(result,failure) }); } 选项3 更新视图模型以采用复杂类型,这不需要更改角度代码. public class ListByCompanyModel { public int CompanyId {get;set;} } [HttpPost] // change to HttpGet [Route("GetAssetListByCompany")] public IActionResult GetAssetListByCompany([FromBody] ListByCompanyModel model) // use FromQuery (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |