为什么在运行管道时出现错误?

时间:2020-02-20 15:23:51

标签: c# asp.net-mvc azure-devops azure-pipelines

我有一个相当大的项目,我使用Azure Pipelines来自动化部署。由于使用了我们的一个库,因此我使用了本地构建代理。

但是,在进入发布步骤时,项目突然失败了。我试图重建几次。我已经浏览了日志,但它们实际上没有任何意义。

2020-02-20T14:18:19.3341737Z ##[error]Path\To\File\Edit.cshtml(201,0): Error CS1525: Invalid expression term '.'

问题是当我在本地发布时没有错误。文件所引用的部分是可为空的日期时间。它引发了少数这些错误,所有这些错误都引用了可为null的datetime对象。我可以认为最近发生的唯一变化是我安装了VS2019。但是我的管道仍然设置为VS2017。日志还显示它正在使用msbuild 15.0。

我在这里有点茫然。有人知道我可能会错过的吗?还是我没有看到的一些故障排除步骤?如果需要任何其他信息,我也有完整的失败构建日志。

Edit.cshtml的内容

@model Project.Portal.Domain.Models.CompanyContact.EditViewModel

@{
    ViewBag.Title = "Edit Company Contact";
    Layout = "~/Views/Shared/_Popup.cshtml";
}

@using (Html.BeginForm("Edit", "CompanyContact"))
{
    <div>
        @Html.ValidationSummary()
    </div>

    <div id="companyContactDetail">
        @Html.HiddenFor(x => x.Id)
        @Html.HiddenFor(x => x.CompanyId)
        @Html.HiddenFor(x => x.ContactId)
        @Html.HiddenFor(x => x.CreatedBy)
        @Html.HiddenFor(x => x.CreatedOn)
        @Html.HiddenFor(x => x.ModifiedBy)
        @Html.HiddenFor(x => x.ModifiedOn)
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.IsPrimary)
                <br />
                @Html.Kendo().CheckBoxFor(x => x.IsPrimary).Label(string.Empty)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.IsSecondary)
                <br />
                @Html.Kendo().CheckBoxFor(x => x.IsSecondary).Label(string.Empty)
            </div>
        </div>
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.IsOwner)
                <br />
                @Html.Kendo().CheckBoxFor(x => x.IsOwner).Label(string.Empty)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.OwnershipPercentage)
                <br />
                @Html.Kendo().NumericTextBoxFor(x => x.OwnershipPercentage).Enable(Model.IsOwner)
            </div>
        </div>
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.IsGuarantor)
                <br />
                @Html.Kendo().CheckBoxFor(x => x.IsGuarantor).Label(string.Empty)
            </div>
        </div>
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-12 text-center">
                <a href="#" onclick="window.parent.$('#CompanyContact-Window').data('kendoWindow').close();" class="btn btn-warning">Cancel</a>
                <a href="#" onclick="showContactDetail();" class="btn btn-primary">Next</a>
            </div>
        </div>
    </div>

    <div id="contactDetail" style="display: none;">
        @Html.HiddenFor(x => x.Contact.Id)
        @Html.HiddenFor(x => x.Contact.SocialSecurityNumber)
        @Html.HiddenFor(x => x.Contact.EditSocialSecurityNumber)
        @Html.HiddenFor(x => x.Contact.CreatedBy)
        @Html.HiddenFor(x => x.Contact.CreatedOn)
        @Html.HiddenFor(x => x.Contact.ModifiedBy)
        @Html.HiddenFor(x => x.Contact.ModifiedOn)
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.FirstName)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.FirstName)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.LastName)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.LastName)
            </div>
        </div>
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.Title)
                <br/>
                @Html.Kendo().TextBoxFor(x => x.Contact.Title)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.FicoScore)
                <br/>
                @Html.Kendo().NumericTextBoxFor(x => x.Contact.FicoScore).Decimals(0).Format("n0")
                @Html.ValidationMessageFor(x => x.Contact.FicoScore)
            </div>
        </div>
        @if (Project.Portal.Common.Security.CurrentUser.CanEditSocialSecurityNumber())
        {
            <div class="row" style="padding-top: 10px;">
                <div class="col-xs-12">
                    @Html.LabelFor(x => x.Contact.SocialSecurityNumber)
                    <br />
                    <a href="#" id="editSSN" onclick="editSSN();" style="display: @(Model.Contact.EditSocialSecurityNumber ? "none" : "block");">Edit Social Security Number</a>
                    <a href="#" id="cancelSSN" onclick="cancelSSNEdit();" style="display: @(Model.Contact.EditSocialSecurityNumber ? "block" : "none");">Cancel Social Security Number Edit</a>
                </div>
                <div id="ssnEdit" style="display: @(Model.Contact.EditSocialSecurityNumber ? "block" : "none");">
                    <div class="col-xs-6">
                        @Html.Kendo().MaskedTextBoxFor(x => x.Contact.NewSocialSecurityNumber).Mask("999-99-9999")
                    </div>
                    <div class="col-xs-6">
                        @Html.Kendo().MaskedTextBoxFor(x => x.Contact.ConfirmNewSocialSecurityNumber).Mask("999-99-9999")
                    </div>
                </div>
            </div>
        }
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.Address1)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.Address1)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.Address2)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.Address2)
            </div>
        </div>
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.City)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.City)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.State)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.State)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.ZipCode)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.ZipCode)
            </div>
            <div class="col-xs-6">
                @Html.LabelFor(x => x.Contact.Country)
                <br />
                @Html.Kendo().TextBoxFor(x => x.Contact.Country)
            </div>
        </div>
        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-12 text-center">
                <a href="#" onclick="showCompanyContactDetail();
" class="btn btn-primary">Previous</a>
                <a href="#" onclick="window.parent.$('#CompanyContact-Window').data('kendoWindow').close();" class="btn btn-warning">Cancel</a>
                <a href="#" onclick="showContactEmailAndPhoneDetail();" class="btn btn-primary">Next</a>
            </div>
        </div>
    </div>

    <div id="contactEmaiAndPhoneDetail" style="display: none;">

        <div class="row" style="padding-top: 10px;">
            <label>Email(s)</label>
            <a class="pull-right" href="#" onclick="addNewEmail();">Add New</a>
            <hr />
            <div id="contactEmails">
                @if (Model.Contact.ContactEmails != null)
                {
                    foreach (var model in Model.Contact.ContactEmails)
                    {
                        @Html.Partial("~/Views/ContactEmail/CompanyContactEdit.cshtml", model)
                    }
                }
            </div>
        </div>

        <div class="row" style="padding-top: 10px;">
            <label>Phone(s)</label>
            <a class="pull-right" href="#" onclick="addNewPhoneNumber();">Add New</a>
            <hr />
            <div id="contactPhoneNumbers">
                @if (Model.Contact.ContactPhoneNumbers != null)
                {
                    foreach (var model in Model.Contact.ContactPhoneNumbers)
                    {
                        @Html.Partial("~/Views/ContactPhoneNumber/CompanyContactEdit.cshtml", model)
                    }
                }
            </div>
        </div>

        <div class="row" style="padding-top: 10px;">
            <div class="col-xs-12 text-center">
                <a href="#" onclick="showContactDetail();" class="btn btn-primary">Previous</a>
                <a href="#" onclick="window.parent.$('#CompanyContact-Window').data('kendoWindow').close();" class="btn btn-warning">Cancel</a>
                <button type="submit" class="btn btn-success" onclick="kendo.ui.progress($('body'), true);">Save</button>
            </div>
        </div>
    </div>
}

<script type="text/javascript">
    var contactId = @Model.Contact.Id;
    var nextEmailIndex = @(Model.Contact.ContactEmails?.Count ?? 0);
    var nextPhoneNumberIndex = @(Model.Contact.ContactPhoneNumbers?.Count ?? 0);

    $(document).ready(function () {
        $("#@Html.IdFor(x => x.IsPrimary)").click(function () {
            if ($(this).prop("checked")) {
                $("#@Html.IdFor(x => x.IsSecondary)").prop("checked", false);
            }
        });

        $("#@Html.IdFor(x => x.IsSecondary)").click(function () {
            if ($(this).prop("checked")) {
                $("#@Html.IdFor(x => x.IsPrimary)").prop("checked", false);
            }
        });

        $("#@Html.IdFor(x => x.IsOwner)").click(function () {
            var ownershipPercentage = $("#@Html.IdFor(x => x.OwnershipPercentage)").data("kendoNumericTextBox");

            if ($(this).prop("checked")) {
                ownershipPercentage.enable(true);
            } else {
                ownershipPercentage.enable(false);
            }
        });
    });

    function showContactDetail() {
        $("#companyContactDetail").hide();
        $("#contactEmaiAndPhoneDetail").hide();

        $("#contactDetail").show();

        return false;
    }

    function showCompanyContactDetail() {
        $("#contactDetail").hide();
        $("#contactEmaiAndPhoneDetail").hide();

        $("#companyContactDetail").show();

        return false;
    }

    function showContactEmailAndPhoneDetail() {
        $("#companyContactDetail").hide();
        $("#contactDetail").hide();

        $("#contactEmaiAndPhoneDetail").show();

        return false;
    }

    function addNewEmail() {
        var div = $("#contactEmails");

        kendo.ui.progress($("#contactEmails"), true);

        $.ajax({
            url: "@Url.Action("CompanyContactAdd", "ContactEmail")?contactId=" + contactId,
            type: "POST",
        success: function(e) {
            div.append(e);

            kendo.ui.progress($("#contactEmails"), false);
        }
    });

    return false;
    }

    function addNewPhoneNumber() {
        var div = $("#contactPhoneNumbers");

        kendo.ui.progress($("#contactPhoneNumbers"), true);

        $.ajax({
            url: "@Url.Action("CompanyContactAdd", "ContactPhoneNumber")?contactId=" + contactId,
            type: "POST",
            success: function(e) {
                div.append(e);

                kendo.ui.progress($("#contactPhoneNumbers"), false);
            }
        });

        return false;
    }

    function editSSN() {
        $("#editSSN").hide();
        $("#cancelSSN").show();
        $("#ssnEdit").show();

        $("#@Html.IdFor(x => x.Contact.EditSocialSecurityNumber)").val("True");
    }

    function cancelSSNEdit() {
        $("#ssnEdit").hide();
        $("#cancelSSN").hide();
        $("#editSSN").show();

        $("#@Html.IdFor(x => x.Contact.EditSocialSecurityNumber)").val("False");
    }
</script>

编辑2:管道详细信息

pool:
  name: Default
  demands:
  - msbuild
  - visualstudio

variables:
  BuildPlatform: 'any cpu'
  BuildConfiguration: 'debug'

steps:
- task: NuGetToolInstaller@0
  displayName: 'Use NuGet 4.4.1'
  inputs:
    versionSpec: 4.4.1

- task: NuGetInstaller@0
  displayName: 'NuGet restore Project.sln'
  inputs:
    solution: '$(Parameters.solution)'

- task: VSBuild@1
  displayName: 'Build solution Project.sln'
  inputs:
    solution: '$(Parameters.solution)'
    vsVersion: 15.0
    platform: '$(BuildPlatform)'
    configuration: '$(BuildConfiguration)'

- task: PublishSymbols@1
  displayName: 'Publish symbols path'
  inputs:
    SearchPattern: '**\bin\**\*.pdb'
  continueOnError: true

- task: VSBuild@1
  displayName: 'Publish Solution Project.sln'
  inputs:
    solution: Project.sln
    vsVersion: 15.0
    msbuildArgs: '/P:PublishProfile=Development /P:DeployOnBuild=true'
    platform: '$(BuildPlatform)'
    configuration: '$(BuildConfiguration)'
    clean: true

- task: CopyFiles@1
  displayName: 'Copy Portal Files'
  inputs:
    SourceFolder: '$(build.sourcesdirectory)'
    Contents: 'Project.Portal.Presentation.Mvc\Publish\**'
    TargetFolder: '$(build.artifactstagingdirectory)\Website'

- task: CopyFiles@1
  displayName: 'Copy API Files'
  inputs:
    SourceFolder: '$(build.sourcesdirectory)'
    Contents: 'Project.Portal.Presentation.Api\Publish\**'
    TargetFolder: '$(build.artifactstagingdirectory)\Api'

- task: CopyFiles@1
  displayName: 'Copy Customer Files'
  inputs:
    SourceFolder: '$(build.sourcesdirectory)'
    Contents: 'Project.Portal.Presentation.Customer\Publish\**'
    TargetFolder: '$(build.artifactstagingdirectory)\Customer'

- task: CopyFiles@1
  displayName: 'Copy DB Files'
  inputs:
    SourceFolder: '$(build.sourcesdirectory)'
    Contents: 'Project.Portal.Data.Database\bin\Debug\Project.Portal.Data.Database.dacpac'
    TargetFolder: '$(build.artifactstagingdirectory)\Database'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: drop'
  inputs:
    ArtifactName: '$(Parameters.ArtifactName)'

修改3: 因此,我将代码库恢复为最新的已知工作版本,然后再次尝试。然后我遇到了相同的错误。

1 个答案:

答案 0 :(得分:2)

由于可以使用本地vs2019正常发布,因此可以尝试在VSBuild任务中设置vsVersion: 16.0vsVersion: 16.0代表vs2019),并确保VS IDE已安装相关的工作负载和组件。

此外,您可以尝试将p:PrecompileBeforePublish=true;EnableUpdateable=false添加到msbuildArgs。

enter image description here

如果以上方法均无效,则可以共享PUBXML文件以进行进一步调查。