C# 使用AmazonS3和Route53 API以编程方式设置静态网站

C# 使用AmazonS3和Route53 API以编程方式设置静态网站,c#,amazon-web-services,amazon-s3,amazon-route53,C#,Amazon Web Services,Amazon S3,Amazon Route53,假设我已经购买了一个IP地址为203.0.113.2的域名example.com。使用C#和AmazonWebServicesSDK for.NET2.0.2.2,我想使用AmazonS3和Route53创建一个使用自定义域的静态网站。手册中描述了手动过程 尝试创建别名时,我收到一条异常消息: Invalid XML ; cvc-complex-type.2.4.a: Invalid content was found starting with element 'AliasTarget'. O

假设我已经购买了一个IP地址为203.0.113.2的域名example.com。使用C#和AmazonWebServicesSDK for.NET2.0.2.2,我想使用AmazonS3和Route53创建一个使用自定义域的静态网站。手册中描述了手动过程

尝试创建别名时,我收到一条异常消息:

Invalid XML ; cvc-complex-type.2.4.a: Invalid content was found starting with element 'AliasTarget'.
One of '{"https://route53.amazonaws.com/doc/2012-12-12/":ResourceRecords}' is expected.
首先,我在AmazonS3中创建或更新了一个bucket(例如“example.com”)。如果已经存在,则删除内容

using (var client = AWSClientFactory.CreateAmazonS3Client(RegionEndpoint.USWest1))
{
    if (!S3BucketExists(name, client))
    {
        client.PutBucket(new PutBucketRequest
        {
            BucketName = name,
            BucketRegion = S3Region.USW1,
            CannedACL = S3CannedACL.PublicRead
        });
    }
    else
    {
        var request = new ListObjectsRequest
        {
            BucketName = name
        };
        var objects = client.ListObjects(request).S3Objects;
        foreach (var o in objects)
        {
            client.DeleteObject(new DeleteObjectRequest
            {
                BucketName = name,
                Key = o.Key
            });
        }
        client.PutACL(new PutACLRequest
        {
            CannedACL = S3CannedACL.PublicRead, 
            BucketName = name
        });
    }

    client.PutBucketWebsite(new PutBucketWebsiteRequest
    {
        BucketName = name,
        WebsiteConfiguration = new WebsiteConfiguration
        {
            ErrorDocument = "404.html",
            IndexDocumentSuffix = "index.html"
        }
    });

    CreateObject(name, client, "index.html", "text/html", "<p>The site is under maintenance</p>");
    CreateObject(name, client, "404.html", "text/html", "<p>Not Found</p>");
}
使用(var client=AWSClientFactory.CreateAmazonS3Client(RegionEndpoint.USWest1))
{
如果(!S3BucketExists(名称、客户端))
{
client.PutBucket(新的PutBucketRequest
{
BucketName=名称,
BucketRegion=S3Region.USW1,
CannedACL=S3CannedACL.PublicRead
});
}
其他的
{
var请求=新的ListObjectsRequest
{
BucketName=名称
};
var objects=client.ListObjects(请求).S3Objects;
foreach(对象中的var o)
{
client.DeleteObject(新的DeleteObjectRequest
{
BucketName=名称,
键
});
}
client.PutACL(新PutACL请求
{
CannedACL=S3CannedACL.PublicRead,
BucketName=名称
});
}
client.PutBucketWebsite(新的PutBucketWebsiteRequest
{
BucketName=名称,
WebsiteConfiguration=新的WebsiteConfiguration
{
ErrorDocument=“404.html”,
IndexDocumentSuffix=“index.html”
}
});
CreateObject(名称、客户端、“index.html”、“text/html”、“网站正在维护中”

”; CreateObject(名称,客户端,“404.html”,“text/html”,“未找到”; }
S3BucketExists返回bucket是否存在,CreateObject创建一个简单页面并将其上传到bucket。为了简洁起见,省略了它。我能够毫无问题地连接到S3托管站点

然后,我使用Route 53 API更新现有托管区域或为“example.com”创建一个托管区域。将删除除SOA和NS条目之外的所有资源

using (var client = AWSClientFactory.CreateAmazonRoute53Client())
{
    var hostedZone = FindHostedZoneByName(client, domainName);
    if (hostedZone != null)
    {
        var resourceRecordSets = client.ListResourceRecordSets(new ListResourceRecordSetsRequest
        {
            HostedZoneId = hostedZone.Id,
        });

        bool hasElements = false;
        var request1 = new ChangeResourceRecordSetsRequest
        {
            HostedZoneId = hostedZone.Id,
            ChangeBatch = new ChangeBatch
            {
                Changes = new List<Change>()
            }
        };
        foreach (var resourceRecordSet in resourceRecordSets.ResourceRecordSets)
        {
            switch (resourceRecordSet.Type)
            {
                case "SOA":
                case "NS":
                    continue;
            }

            var change = new Change
            {
                Action = "DELETE",
                ResourceRecordSet = resourceRecordSet
            };
            request1.ChangeBatch.Changes.Add(change);
            hasElements = true;
        }

        if (hasElements)
        {
            var response = client.ChangeResourceRecordSets(request1);
        }
    }
    else
    {
        hostedZone = CreateHostedZone(client, domainName);
    }

    var hostedZoneId = hostedZone.Id;
    var request = new ChangeResourceRecordSetsRequest
    {
        HostedZoneId = hostedZoneId,
        ChangeBatch = new ChangeBatch
        {
            Changes = new List<Change>
            {
                new Change
                {
                    Action = ChangeAction.CREATE,
                    ResourceRecordSet = new ResourceRecordSet
                    {
                        Name = GetQualifiedName(domainName),
                        Type = RRType.A,
                        TTL = 300,
                        AliasTarget = new AliasTarget()
                        {
                            HostedZoneId = "Z2F56UZL2M1ACD",
                            DNSName = "s3-website-us-west-1.amazonaws.com.",
                        },
                    },
                },
            }
        }
    };
    client.ChangeResourceRecordSets(request);
}
使用(var client=AWSClientFactory.CreateAmazonRoute53Client())
{
var hostedZone=FindHostedZoneByName(客户端,域名);
if(hostedZone!=null)
{
var resourceRecordSets=client.ListResourceRecordSets(新ListResourceRecordSetRequest
{
HostedZoneId=hostedZone.Id,
});
bool=false;
var request1=新的ChangeResourceRecordSetRequest
{
HostedZoneId=hostedZone.Id,
ChangeBatch=新的ChangeBatch
{
更改=新列表()
}
};
foreach(resourceRecordSet.resourceRecordSet中的var resourceRecordSet)
{
开关(resourceRecordSet.Type)
{
案例“SOA”:
案例“NS”:
继续;
}
var变更=新变更
{
Action=“删除”,
ResourceRecordSet=ResourceRecordSet
};
request1.ChangeBatch.Changes.Add(变更);
hasElements=true;
}
if(元素)
{
var response=client.changeresourcerecordset(request1);
}
}
其他的
{
hostedZone=CreateHostedZone(客户端,域名);
}
var hostedZoneId=hostedZone.Id;
var请求=新的ChangeResourceRecordSetRequest
{
HostedZoneId=HostedZoneId,
ChangeBatch=新的ChangeBatch
{
更改=新列表
{
新变化
{
Action=ChangeAction.CREATE,
ResourceRecordSet=新的ResourceRecordSet
{
Name=GetQualifiedName(域名),
类型=RRType.A,
TTL=300,
AliasTarget=新的AliasTarget()
{
HostedZoneId=“Z2F56UZL2M1ACD”,
DNSName=“s3-website-us-west-1.amazonaws.com。”,
},
},
},
}
}
};
client.changeresourcerecordset(请求);
}
托管的区域id(“Z2F56UZL2M1ACD”)和DNS名称(“s3-WESTER-us-west-1.amazonaws.com”)是公共知识和服务

对ChangeResourceRecordset的调用引发异常。我创建了一个空的ResourceRecords列表,记录为“203.0.113.2”,但没有创建别名


也就是说,我可以在以后使用“Route 53管理控制台”手动创建Amazon S3站点的别名。我肯定我遗漏了一些小东西。

重新阅读文档后,发现在指定别名时无法指定TTL。下面的更改是有效的。将创建
ChangeResourceRecordSetRequest
实例的代码替换为以下代码:

var request = new ChangeResourceRecordSetsRequest
{
    HostedZoneId = hostedZoneId,
    ChangeBatch = new ChangeBatch
    {
        Changes = new List<Change>
        {
            new Change
            {
                Action = ChangeAction.CREATE,
                ResourceRecordSet = new ResourceRecordSet
                {
                    Name = GetQualifiedName(domainName),
                    Type = RRType.A,
                    AliasTarget = new AliasTarget
                    {
                        HostedZoneId = "Z2F56UZL2M1ACD",
                        DNSName = "s3-website-us-west-1.amazonaws.com.",
                        EvaluateTargetHealth = false,
                    },
                },
            },
        }
    }
};
var request=newchangeresourcerecordsetrequest
{
HostedZoneId=HostedZoneId,
ChangeBatch=新的ChangeBatch
{
更改=新列表
{
新变化
{
Action=ChangeAction.CREATE,
ResourceRecordSet=新的ResourceRecordSet
{
Name=GetQualifiedName(域名),
类型=RRType.A,
AliasTarget=新的AliasTarget
{
HostedZoneId=“Z2F56UZL2M1ACD”,
DNSName=“s3-website-us-west-1.amazonaws.com。”,
evaluateTargetAlth=false,
},
},
},
}
}
};
当输出值为