Issue of connecting REST service by Visual Studio

  • 9 April 2014
  • 3 replies
  • 4 views

I am learning how to consume K2 REST service via Visual Studio by sample code provided by Developer Document. The code will list below.

 

The issue is that when I established WebHttpRequest and tried to get response from server, the program throw an execption with "401 unauthorized".

 

I am wondering how to set Request's credentials for connecting K2 REST service.

 

PS: when type REST service's URL in IE, it is normal to get XML contents.

 

Sample Code:

 

Default.aspx:<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestASP_Web_Application_for_REST._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title></title></head><body>    <form id="form1" runat="server">    <div>           <asp:Button ID="getDataButton" runat="server" onclick="getDataButton_Click" Text="Get Worklist Data" />        <br />        <table style="width: 100%;">            <tr>                <td>                    Process Name:                </td>                <td>                    <asp:TextBox ID="processName" runat="server"></asp:TextBox>                </td>            </tr>            <tr>                <td>                    Serial Number:                </td>                <td>                    <asp:TextBox ID="serialNumber" runat="server"></asp:TextBox>                </td>            </tr>            <tr>                <td>                    Alloocated User:                </td>                <td>                    <asp:TextBox ID="allocatedUser" runat="server"></asp:TextBox>                </td>            </tr>            <tr>                <td>                    Process DataField Value:                </td>                <td>                    <asp:TextBox ID="procDataField" runat="server"></asp:TextBox>                </td>            </tr>            <tr>                <td>                    Activity DataField Value:                </td>                <td>                    <asp:TextBox ID="actDataField" runat="server"></asp:TextBox>                </td>            </tr>            <tr>                <td>                    Available Actions:                </td>                <td>                    <asp:DropDownList ID="actionsDropDownList" runat="server" Width="129px">                    </asp:DropDownList>                </td>            </tr>        </table>                  </div>    </form></body></html> //Default.aspx.cs:using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Net;using System.Xml.Linq;using System.Xml;using System.IO; namespace TestASP_Web_Application_for_REST{    public partial class _Default : System.Web.UI.Page    {        // Change the RestURL to match your workspace environment         private const string RestUrl = "http://sav-docs:81/K2Services/REST.svc/Worklist/Items?piDataField=true&actXmlField=true";        private static readonly XNamespace WorklistNamespace = "http://schemas.k2.com/worklist/d1";        private static readonly XNamespace ActivityNamespace = "http://schemas.k2.com/activity/d1";        private static readonly XNamespace ProcessNamespace = "http://schemas.k2.com/process/d1";        private static readonly XNamespace EventNamespace = "http://schemas.k2.com/event/d1";               protected void Page_Load(object sender, EventArgs e)        {         }         protected void getDataButton_Click(object sender, EventArgs e)        {            GetData();        }         private void GetData()        {            // create the web request             HttpWebRequest request = WebRequest.Create(RestUrl) as HttpWebRequest;             // Assign Credentials            request.Credentials = CredentialCache.DefaultCredentials;             // get response            XDocument responseDocument;            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)            using (Stream responseStream = response.GetResponseStream())            using (XmlReader responseReader = XmlReader.Create(responseStream))            {                responseDocument = XDocument.Load(responseReader);            }             //Call method to extract a specific value            PopulateAllocatedUserTextBox(responseDocument);            PopulateActivityDataTextBox(responseDocument);            PopulateProcessDataTextBox(responseDocument);            PopulateWorklistItemSerialNumberTextBox(responseDocument);            PopulateProcessNameTextBox(responseDocument);            PopulateActions(responseDocument);        }         private void PopulateActions(XDocument responseDocument)        {            var actionsQuery =                from worklistItemCollection in responseDocument.Elements(WorklistNamespace + "WorklistItemCollection")                from worklistItem in worklistItemCollection.Elements(WorklistNamespace + "WorklistItem")                from action in worklistItem.Elements(WorklistNamespace + "Action")                select new                {                    SerialNumber = (string)worklistItem.Attribute("SerialNumber"),                    Name = (string)action.Attribute("Name"),                    Batchable = (bool)action.Attribute("Batchable")                };                       foreach (var action in actionsQuery)            {                var listItem = new ListItem()                {                                       Text = action.Name,                                       Value = action.SerialNumber,                    Enabled = action.Batchable,                                  };                 string thisSerialNumber = listItem.Value.ToString();                if (thisSerialNumber == serialNumber.Text)                {                    actionsDropDownList.Items.Add(listItem);                }            }        }         private void PopulateProcessDataTextBox(XDocument responseDocument)        {            var dataFieldValueQuery =                from worklistItemCollection in responseDocument.Elements(WorklistNamespace + "WorklistItemCollection")                from worklistItem in worklistItemCollection.Elements(WorklistNamespace + "WorklistItem")                from processInstance in worklistItem.Elements(ProcessNamespace + "ProcessInstance")                from dataField in processInstance.Elements(ProcessNamespace + "DataField")                where (string)dataField.Attribute("Name") == "MyProcessDataField"                select (string)dataField;             var firstResult = dataFieldValueQuery.FirstOrDefault();            procDataField.Text = firstResult;        }              private void PopulateActivityDataTextBox(XDocument responseDocument)        {            var dataFieldValueQuery =                from worklistItemCollection in responseDocument.Elements(WorklistNamespace + "WorklistItemCollection")                from worklistItem in worklistItemCollection.Elements(WorklistNamespace + "WorklistItem")                from activityInstanceDestination in worklistItem.Elements(ActivityNamespace + "ActivityInstanceDestination")                from dataField in activityInstanceDestination.Elements(ProcessNamespace + "DataField")                where (string)dataField.Attribute("Name") == "MyActivityDataField"                select (string)dataField;                       var firstResult = dataFieldValueQuery.FirstOrDefault();            actDataField.Text = firstResult;        }         private void PopulateAllocatedUserTextBox(XDocument responseDocument)        {            var allocatedUserFieldValueQuery =                from worklistItemCollection in responseDocument.Elements(WorklistNamespace + "WorklistItemCollection")                from worklistItem in worklistItemCollection.Elements(WorklistNamespace + "WorklistItem")                select (string)worklistItem.Attribute("AllocatedUser").Value;             var firstResult = allocatedUserFieldValueQuery.FirstOrDefault();            allocatedUser.Text = firstResult;        }         private void PopulateProcessNameTextBox(XDocument responseDocument)        {            var processFullNameFieldValueQuery =                from worklistItemCollection in responseDocument.Elements(WorklistNamespace + "WorklistItemCollection")                from worklistItem in worklistItemCollection.Elements(WorklistNamespace + "WorklistItem")                from processInstance in worklistItem.Elements(ProcessNamespace + "ProcessInstance")                select (string)processInstance.Attribute("FullName").Value;             var firstResult = processFullNameFieldValueQuery.FirstOrDefault();            processName.Text = firstResult;        }               private void PopulateWorklistItemSerialNumberTextBox(XDocument responseDocument)        {            var processFullNameFieldValueQuery =                from worklistItemCollection in responseDocument.Elements(WorklistNamespace + "WorklistItemCollection")                from worklistItem in worklistItemCollection.Elements(WorklistNamespace + "WorklistItem")                select (string)worklistItem.Attribute("SerialNumber").Value;             var firstResult = processFullNameFieldValueQuery.FirstOrDefault();            serialNumber.Text = firstResult;        }    }} 

 


3 replies

Badge +7

Hello,


 


Please try the following and see if you're still getting the same result:


The following actions can be followed to correct this problem:



  • Check the IIS logs for the 401 error to see what user is being passed to runtime services

  • You might also want to try opening the relevant asmx URL in the browser from the machine you are running the tool. This is just to verify that there are no odd permission or configuration issues. This is usually a cause if there is no Kerberos delegation issues involved (especially for IIS7)


Hope this will resolve the problem


 


Kind regards


Nelly

Badge +4

Hi wangyan,


 


If I understand your issue correct here, please look at the following.


 


>Open iis manager.


>Expand "iis server name"


>Expand "Sites"


>Go to K2 site or Site running the rest service.


>Double click on "Authentication"


>Enable "Anonymous Authentication"


>Note the response type of "Windows Authentication" is the Error 401 code.


 


Test if this has resolved the issue.


 


Hope this helps


 


Regards


Quintin

Hi,  @wangyan,

 

I also encountered the exactly the same problem. My I know how you solved this issue in the end?

 

Thank you and regards,

SH

Reply