Javascript 400(错误请求),该参数是一个url
我试图用一个参数执行get请求,该参数实际上是一个字符串,但该字符串是一个url 所以我得到了这个错误:Javascript 400(错误请求),该参数是一个url,javascript,.net,reactjs,asp.net-web-api,asp.net-web-api2,Javascript,.net,Reactjs,Asp.net Web Api,Asp.net Web Api2,我试图用一个参数执行get请求,该参数实际上是一个字符串,但该字符串是一个url 所以我得到了这个错误: react-adal.js:50 OPTIONS https://abc-app.azurewebsites.net/api/Page/https://abcde.sharepoint.com/sites/Site1 400 (Bad Request) 我的剧本是这样的: import React, { Component } from 'react'; import { Row, Col
react-adal.js:50 OPTIONS https://abc-app.azurewebsites.net/api/Page/https://abcde.sharepoint.com/sites/Site1 400 (Bad Request)
我的剧本是这样的:
import React, { Component } from 'react';
import { Row, Col, Tabs, Menu, Dropdown, Button, Icon, message } from 'antd';
import PageHeader from '../../components/utility/pageHeader';
import Box from '../../components/utility/box';
import LayoutWrapper from '../../components/utility/layoutWrapper';
import ContentHolder from '../../components/utility/contentHolder';
import basicStyle from '../../settings/basicStyle';
import IntlMessages from '../../components/utility/intlMessages';
import { Cascader } from 'antd';
import { adalApiFetch } from '../../adalConfig';
export default class extends Component {
constructor(props) {
super(props);
this.state = {options:[]};
this.loadData = this.loadData.bind(this);
}
componentDidMount() {
adalApiFetch(fetch, "/SiteCollection", {})
.then(response => response.json())
.then(json => {
console.log(json);
const firstLevelOptions = json.map(post => ({
value: post.Url,
label: post.Title,
isLeaf: false
}));
this.setState({
options: firstLevelOptions
});
});
}
onChange = (value, selectedOptions) => {
console.log("value:", value, "selectedOptions", selectedOptions);
}
loadData = (selectedOptions) => {
console.log("loaddata", selectedOptions);
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
const options = {
method: 'get',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
adalApiFetch(fetch, "/Page/"+targetOption.value, options)
.then(response => response.json())
.then(json => {
targetOption.loading = false;
console.log(json);
const secondLevelOptions = json.map(comment => ({
value: comment.id,
label: comment.body,
isLeaf: true
}));
targetOption.children = secondLevelOptions;
this.setState({
options: [...this.state.options],
});
}
);
};
render(){
const { rowStyle, colStyle, gutter } = basicStyle;
const TabPane = Tabs.TabPane;
return (
<div>
<LayoutWrapper>
<PageHeader>{<IntlMessages id="pageTitles.PageAdministration" />}</PageHeader>
<Row style={rowStyle} gutter={gutter} justify="start">
<Col md={12} sm={12} xs={24} style={colStyle}>
<Box
title={<IntlMessages id="pageTitles.siteCollectionsTitle" />}
subtitle={<IntlMessages id="pageTitles.siteCollectionsTitle" />}
>
<ContentHolder>
<Cascader
options={this.state.options}
loadData={this.loadData}
onChange={this.onChange}
changeOnSelect
/>
</ContentHolder>
</Box>
</Col>
</Row>
</LayoutWrapper>
</div>
);
}
}
[Authorize]
public class PageController : ApiController
{
[HttpGet]
public async Task<ListItemCollection> Get(string sitecollectionUrl)
{
var tenant = await TenantHelper.GetActiveTenant();
var siteCollectionStore = CosmosStoreFactory.CreateForEntity<TenantManagementWebApi.Entities.SiteCollection>();
await siteCollectionStore.RemoveAsync(x => x.Title != string.Empty); // Removes all the entities that match the criteria
string domainUrl = tenant.TestSiteCollectionUrl;
string tenantName = domainUrl.Split('.')[0];
string tenantAdminUrl = tenantName + "-admin.sharepoint.com";
KeyVaultHelper keyVaultHelper = new KeyVaultHelper();
await keyVaultHelper.OnGetAsync(tenant.SecretIdentifier);
using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetSharePointOnlineAuthenticatedContextTenant(sitecollectionUrl, tenant.Email, keyVaultHelper.SecretValue))
{
var pagesLibrary = context.Web.GetPagesLibrary();
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
var pages = pagesLibrary.GetItems(query);
return pages;
};
}
}
import React,{Component}来自'React';
从“antd”导入{行、列、选项卡、菜单、下拉列表、按钮、图标、消息};
从“../../components/utility/PageHeader”导入PageHeader;
从“../../components/utility/Box”导入框;
从“../../components/utility/LayoutWrapper”导入LayoutWrapper;
从“../../components/utility/ContentHolder”导入ContentHolder;
从“../../settings/basicStyle”导入basicStyle;
从“../../components/utility/IntlMessages”导入IntlMessages;
从“antd”导入{Cascader};
从“../../adalConfig”导入{adalApiFetch};
导出默认类扩展组件{
建造师(道具){
超级(道具);
this.state={options:[]};
this.loadData=this.loadData.bind(this);
}
componentDidMount(){
adalApiFetch(fetch,“/sitecolection”,{})
.then(response=>response.json())
。然后(json=>{
log(json);
const firstLevelOptions=json.map(post=>({
值:post.Url,
标签:post.Title,
岛:假
}));
这是我的国家({
选项:firstLevelOptions
});
});
}
onChange=(值,选择选项)=>{
log(“值:”,值,“selectedOptions”,selectedOptions);
}
loadData=(选择的选项)=>{
console.log(“加载数据”,选择选项);
const targetOption=selectedOptions[selectedOptions.length-1];
targetOption.loading=true;
常量选项={
方法:“get”,
标题:{
“内容类型”:“应用程序/json;字符集=utf-8”
}
};
adalApiFetch(获取“/Page/”+targetOption.value,选项)
.then(response=>response.json())
。然后(json=>{
targetOption.loading=false;
log(json);
const secondLevelOptions=json.map(注释=>({
值:comment.id,
标签:comment.body,
岛:对
}));
targetOption.children=第二级选项;
这是我的国家({
选项:[…this.state.options],
});
}
);
};
render(){
const{rowStyle,colStyle,gutter}=basicStyle;
const TabPane=Tabs.TabPane;
返回(
{}
);
}
}
我的web api代码如下所示:
import React, { Component } from 'react';
import { Row, Col, Tabs, Menu, Dropdown, Button, Icon, message } from 'antd';
import PageHeader from '../../components/utility/pageHeader';
import Box from '../../components/utility/box';
import LayoutWrapper from '../../components/utility/layoutWrapper';
import ContentHolder from '../../components/utility/contentHolder';
import basicStyle from '../../settings/basicStyle';
import IntlMessages from '../../components/utility/intlMessages';
import { Cascader } from 'antd';
import { adalApiFetch } from '../../adalConfig';
export default class extends Component {
constructor(props) {
super(props);
this.state = {options:[]};
this.loadData = this.loadData.bind(this);
}
componentDidMount() {
adalApiFetch(fetch, "/SiteCollection", {})
.then(response => response.json())
.then(json => {
console.log(json);
const firstLevelOptions = json.map(post => ({
value: post.Url,
label: post.Title,
isLeaf: false
}));
this.setState({
options: firstLevelOptions
});
});
}
onChange = (value, selectedOptions) => {
console.log("value:", value, "selectedOptions", selectedOptions);
}
loadData = (selectedOptions) => {
console.log("loaddata", selectedOptions);
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
const options = {
method: 'get',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
adalApiFetch(fetch, "/Page/"+targetOption.value, options)
.then(response => response.json())
.then(json => {
targetOption.loading = false;
console.log(json);
const secondLevelOptions = json.map(comment => ({
value: comment.id,
label: comment.body,
isLeaf: true
}));
targetOption.children = secondLevelOptions;
this.setState({
options: [...this.state.options],
});
}
);
};
render(){
const { rowStyle, colStyle, gutter } = basicStyle;
const TabPane = Tabs.TabPane;
return (
<div>
<LayoutWrapper>
<PageHeader>{<IntlMessages id="pageTitles.PageAdministration" />}</PageHeader>
<Row style={rowStyle} gutter={gutter} justify="start">
<Col md={12} sm={12} xs={24} style={colStyle}>
<Box
title={<IntlMessages id="pageTitles.siteCollectionsTitle" />}
subtitle={<IntlMessages id="pageTitles.siteCollectionsTitle" />}
>
<ContentHolder>
<Cascader
options={this.state.options}
loadData={this.loadData}
onChange={this.onChange}
changeOnSelect
/>
</ContentHolder>
</Box>
</Col>
</Row>
</LayoutWrapper>
</div>
);
}
}
[Authorize]
public class PageController : ApiController
{
[HttpGet]
public async Task<ListItemCollection> Get(string sitecollectionUrl)
{
var tenant = await TenantHelper.GetActiveTenant();
var siteCollectionStore = CosmosStoreFactory.CreateForEntity<TenantManagementWebApi.Entities.SiteCollection>();
await siteCollectionStore.RemoveAsync(x => x.Title != string.Empty); // Removes all the entities that match the criteria
string domainUrl = tenant.TestSiteCollectionUrl;
string tenantName = domainUrl.Split('.')[0];
string tenantAdminUrl = tenantName + "-admin.sharepoint.com";
KeyVaultHelper keyVaultHelper = new KeyVaultHelper();
await keyVaultHelper.OnGetAsync(tenant.SecretIdentifier);
using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetSharePointOnlineAuthenticatedContextTenant(sitecollectionUrl, tenant.Email, keyVaultHelper.SecretValue))
{
var pagesLibrary = context.Web.GetPagesLibrary();
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
var pages = pagesLibrary.GetItems(query);
return pages;
};
}
}
[授权]
公共类页面控制器:ApiController
{
[HttpGet]
公共异步任务获取(字符串sitecollectionUrl)
{
var tenant=wait TenantHelper.GetActiveTenant();
var siteCollectionStore=CosmosStoreFactory.CreateForEntity();
等待siteCollectionStore.RemoveAsync(x=>x.Title!=string.Empty);//删除符合条件的所有实体
字符串domainUrl=tenant.TestSiteCollectionUrl;
字符串tenantName=domainUrl.Split('.')[0];
字符串tenantAdmin=tenantName+“-admin.sharepoint.com”;
KeyVaultHelper KeyVaultHelper=新的KeyVaultHelper();
等待keyVaultHelper.OnGetAsync(租户.SecretIdentifier);
使用(var context=new OfficeDevPnP.Core.AuthenticationManager().GetSharePointOnlineAuthenticatedContextTenant(sitecollectionUrl、tenant.Email、KeyVault Helper.SecretValue))
{
var pagesLibrary=context.Web.GetPagesLibrary();
CamlQuery=CamlQuery.CreateAllItemsQuery(100);
var pages=pagesLibrary.GetItems(查询);
返回页面;
};
}
}
调用api时,必须将发送的URL编码为参数:
adalApiFetch(fetch, "/Page/"+encodeURIComponent(targetOption.value), options)
您可能需要在后端对其进行解码。取决于路由的配置方式,最终可能与预期操作不匹配 尝试在服务器上使用属性路由,以便更好地控制该操作的路由 在
WebApiConfig
//attribute routing
config.MapHttpAttributeRoutes();
//convention-based routes
//...
更新ApiController以使用catch-all参数
[Authorize]
[RoutePrefix("api/Page")]
public class PageController : ApiController {
//GET api/Page/https://abcde.sharepoint.com/sites/Site1
[HttpGet]
[Route("{*sitecollectionUrl}")]
public async Task<IHttpActionResult> Get(string sitecollectionUrl) {
var tenant = await TenantHelper.GetActiveTenant();
var siteCollectionStore = CosmosStoreFactory.CreateForEntity<TenantManagementWebApi.Entities.SiteCollection>();
await siteCollectionStore.RemoveAsync(x => x.Title != string.Empty); // Removes all the entities that match the criteria
string domainUrl = tenant.TestSiteCollectionUrl;
string tenantName = domainUrl.Split('.')[0];
string tenantAdminUrl = tenantName + "-admin.sharepoint.com";
KeyVaultHelper keyVaultHelper = new KeyVaultHelper();
await keyVaultHelper.OnGetAsync(tenant.SecretIdentifier);
using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetSharePointOnlineAuthenticatedContextTenant(sitecollectionUrl, tenant.Email, keyVaultHelper.SecretValue)) {
var pagesLibrary = context.Web.GetPagesLibrary();
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
var pages = pagesLibrary.GetItems(query);
return Ok(pages);
}
}
}
[授权]
[RoutePrefix(“api/页面”)]
公共类页面控制器:ApiController{
//获取api/页面/https://abcde.sharepoint.com/sites/Site1
[HttpGet]
[路由(“{*sitecollectionUrl}”)]
公共异步任务获取(字符串sitecollectionUrl){
var tenant=wait TenantHelper.GetActiveTenant();
var siteCollectionStore=CosmosStoreFactory.CreateForEntity();
等待siteCollectionStore.RemoveAsync(x=>x.Title!=string.Empty);//删除符合条件的所有实体
字符串domainUrl=tenant.TestSiteCollectionUrl;
字符串tenantName=domainUrl.Split('.')[0];
字符串tenantAdmin=tenantName+“-admin.sharepoint.com”;
KeyVaultHelper KeyVaultHelper=新的KeyVaultHelper();
等待keyVaultHelper.OnGetAsync(租户.SecretIdentifier);
使用(var context=new OfficeDevPnP.Core.AuthenticationManager().GetSharePointOnlineAuthenticatedContextTenant(sitecollectionUrl、tenant.Email、KeyVault Helper.SecretValue)){
var pagesLibrary=context.Web.GetPagesLibrary();
CamlQuery=CamlQuery.CreateAllItemsQuery(100);
var pages=pagesLibrary.GetItems(查询);
返回Ok(页);
}
}
}
您是否尝试过对url参数进行url编码?我还假设正在使用基于默认约定的路由。即