gpt4 book ai didi

javascript - reactjs 组件上的 405(方法不允许)

转载 作者:行者123 更新时间:2023-11-29 20:50:10 25 4
gpt4 key购买 nike

我正在尝试使用 post 方法调用端点。

代码是:

import React, { Component } from 'react';
import { Input} from 'antd';
import Form from '../../components/uielements/form';
import Button from '../../components/uielements/button';
import Notification from '../../components/notification';
import { adalApiFetch } from '../../adalConfig';


const FormItem = Form.Item;

class CreateSiteCollectionForm extends Component {
constructor(props) {
super(props);
this.state = {Alias:'',DisplayName:'', Description:''};
this.handleChangeAlias = this.handleChangeAlias.bind(this);
this.handleChangeDisplayName = this.handleChangeDisplayName.bind(this);
this.handleChangeDescription = this.handleChangeDescription.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
};

handleChangeAlias(event){
this.setState({Alias: event.target.value});
}

handleChangeDisplayName(event){
this.setState({DisplayName: event.target.value});
}

handleChangeDescription(event){
this.setState({Description: event.target.value});
}

handleSubmit(e){
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let data = new FormData();
//Append files to form data
//data.append(

const options = {
method: 'post',
body: JSON.stringify(
{
"Alias": this.state.Alias,
"DisplayName": this.state.DisplayName,
"Description": this.state.Description
}),
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
};

adalApiFetch(fetch, "/SiteCollections/CreateModernSite", options)
.then(response =>{
if(response.status === 204){
Notification(
'success',
'Site collection created',
''
);
}else{
throw "error";
}
})
.catch(error => {
Notification(
'error',
'Site collection not created',
error
);
console.error(error);
});
}
});
}

render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 14 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 14,
offset: 6,
},
},
};
return (
<Form onSubmit={this.handleSubmit}>
<FormItem {...formItemLayout} label="Alias" hasFeedback>
{getFieldDecorator('Alias', {
rules: [
{
required: true,
message: 'Please input your alias',
}
]
})(<Input name="alias" id="alias" onChange={this.handleChangeAlias} />)}
</FormItem>
<FormItem {...formItemLayout} label="Display Name" hasFeedback>
{getFieldDecorator('displayname', {
rules: [
{
required: true,
message: 'Please input your display name',
}
]
})(<Input name="displayname" id="displayname" onChange={this.handleChangedisplayname} />)}
</FormItem>
<FormItem {...formItemLayout} label="Description" hasFeedback>
{getFieldDecorator('description', {
rules: [
{
required: true,
message: 'Please input your description',
}
],
})(<Input name="description" id="description" onChange={this.handleChangeDescription} />)}
</FormItem>

<FormItem {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
Create modern site
</Button>
</FormItem>
</Form>
);
}
}

const WrappedCreateSiteCollectionForm = Form.create()(CreateSiteCollectionForm);
export default WrappedCreateSiteCollectionForm;

webapi 是这个:

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using TenantManagementWebApi.Entities;
using TenantManagementWebApi.Factories;
using Cosmonaut.Extensions;
using Microsoft.Online.SharePoint.TenantAdministration;
using Microsoft.SharePoint.Client;
using OfficeDevPnP.Core.Sites;
using TenantManagementWebApi.Components;

namespace TenantManagementWebApi.Controllers
{
[Authorize]
public class SiteCollectionsController : ApiController
{
// GET: ModernTeamSite
public async Task<List<TenantManagementWebApi.Entities.SiteCollection>> Get()
{
var tenant = await TenantHelper.GetTenantAsync();

using (var cc = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(tenant.TenantAdminUrl, tenant.ClientId, tenant.ClientSecret))
{
Tenant tenantOnline = new Tenant(cc);
SPOSitePropertiesEnumerable siteProps = tenantOnline.GetSitePropertiesFromSharePoint("0", true);
cc.Load(siteProps);
cc.ExecuteQuery();
List<TenantManagementWebApi.Entities.SiteCollection> sites = new List<TenantManagementWebApi.Entities.SiteCollection>();
foreach (var site in siteProps)
{

sites.Add(new TenantManagementWebApi.Entities.SiteCollection()
{
Url = site.Url,
Owner = site.Owner,
Template = site.Template,
Title = site.Title
});
}

return sites;
};
}

[HttpPost]
//[Route("api/SiteCollections/CreateModernSite")]
public async Task<string> CreateModernSite(string Alias, string DisplayName, string Description)
{
var tenant = await TenantHelper.GetTenantAsync();
using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(tenant.TenantAdminUrl, tenant.ClientId, tenant.ClientSecret))
{
var teamContext = await context.CreateSiteAsync(
new TeamSiteCollectionCreationInformation
{
Alias = Alias, // Mandatory
DisplayName = DisplayName, // Mandatory
Description = Description, // Optional
//Classification = Classification, // Optional
//IsPublic = IsPublic, // Optional, default true
}
);
teamContext.Load(teamContext.Web, w => w.Url);
teamContext.ExecuteQueryRetry();
return teamContext.Web.Url;
}
}
}
}

最佳答案

属性路由已启用,根据评论中的屏幕截图,因为 WebApiConfig 具有默认配置

public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Attribute routing.
config.MapHttpAttributeRoutes();

// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

注意基于约定的路由上的 api 前缀。

来自客户端的请求正在向 /SiteCollections/CreateModernSite 发出,这与 Web API 不匹配,因为 API Controller 似乎没有使用属性路由并且请求的 URL 与 Web API 不匹配基于约定的路线。

同样在客户端,当内容类型设置为 'multipart/form-data'

时,在选项中构建了一个 JSON 正文

如果目的是在正文中发布内容,那么您需要在服务器端进行一些更改以使 API 可访问。

[Authorize]
[RoutePrefix("api/SiteCollections")]
public class SiteCollectionsController : ApiController {
// GET api/SiteCollections
[HttpGet]
[Route("")]
public async Task<IHttpActionResult> Get() {
var tenant = await TenantHelper.GetTenantAsync();
using (var cc = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(tenant.TenantAdminUrl, tenant.ClientId, tenant.ClientSecret)) {
var tenantOnline = new Tenant(cc);
SPOSitePropertiesEnumerable siteProps = tenantOnline.GetSitePropertiesFromSharePoint("0", true);
cc.Load(siteProps);
cc.ExecuteQuery();
var sites = siteProps.Select(site =>
new TenantManagementWebApi.Entities.SiteCollection() {
Url = site.Url,
Owner = site.Owner,
Template = site.Template,
Title = site.Title
})
.ToList();
return Ok(sites);
}
}

// POST api/SiteCollections
[HttpPost]
[Route("")]
public async Task<IHttpActionResult> CreateModernSite([FromBody]NewSiteInformation model) {
if(ModelState.IsValid) {
var tenant = await TenantHelper.GetTenantAsync();
using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(tenant.TenantAdminUrl, tenant.ClientId, tenant.ClientSecret)) {
var teamContext = await context.CreateSiteAsync(
new TeamSiteCollectionCreationInformation {
Alias = model.Alias, // Mandatory
DisplayName = model.DisplayName, // Mandatory
Description = model.Description, // Optional
//Classification = Classification, // Optional
//IsPublic = IsPublic, // Optional, default true
}
);
teamContext.Load(teamContext.Web, _ => _.Url);
teamContext.ExecuteQueryRetry();
//204 with location and content set to created URL
return Created(teamContext.Web.Url, teamContext.Web.Url);
}
}
return BadRequest(ModelState);
}

public class NewSiteInformation {
[Required]
public string Alias { get; set; }
[Required]
public string DisplayName { get; set; }
public string Description { get; set; }
//...
}
}

请注意,为 POST 操作、模型验证和返回客户端所期望的正确 HTTP 状态代码包含了正确的强类型对象模型。 (204)

在客户端,更新被调用的 URL 以匹配 API Controller 的路由并更新选项以发送正确的内容类型。

//...

const options = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(
{
Alias: this.state.Alias,
DisplayName: this.state.DisplayName,
Description: this.state.Description
})
};

adalApiFetch(fetch, "api/SiteCollections", options)
.then(response =>{
if(response.status === 204){
Notification(
'success',
'Site collection created',
''
);
}else{
throw "error";
}
})
.catch(error => {
Notification(
'error',
'Site collection not created',
error
);
console.error(error);
});

//...

请注意 headers 如何直接出现在获取选项中,而不是原始代码中的 config.headers

关于javascript - reactjs 组件上的 405(方法不允许),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52353757/

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