Ошибка “Incorrect attribute value type System.Single” при обновлении поля типа float
float value = 123;
var myEntity = new Entity("new_myentity") { Id = myEntityId };
@event["new_myfield"] = value;
service.Update(@event);
Подобный код в CRM 2011 может выдать ошибку “Incorrect attribute value type System.Single”, не смотря на то, что поле new_myfield имеет тип float.
Для решения проблемы достаточно изменить тип переменной value с float на decimal.
Вставка данных в БД SQL из DataSet
string sqlConnectionString = "..."; // Строка подключения к БД SQL
string tableName = "..."; // Имя таблицы в DataSet
DataSet ds; // Заполненный данными DataSet
using (var con = new SqlConnection(sqlConnectionString))
{
con.Open();
using (var insertCmd = con.CreateCommand())
{
insertCmd.CommandText = "INSERT INTO Names (Number, Name) VALUES (@Number, @Name)";
insertCmd.Parameters.Add("Number", SqlDbType.NVarChar, 100, "Номер договора");
insertCmd.Parameters.Add("Name", SqlDbType.NVarChar, 100, "Клиент");
using (var adapter = new SqlDataAdapter())
{
adapter.InsertCommand = insertCmd;
adapter.Update(ds, tableName);
}
}
con.Close();
}
Возможна ситуация, когда и данные есть и ошибок нет, но данные из DataSet в БД не попадают. Такое может быть, например, когда DataSet заполнялся с помощью метода Fill другого DataAdapter или для DataSet был выполнен метод AcceptChanges. В этом случае данные в DataSet помечены как не измененные, и DataAdapter не считает нужным что-то с ними делать.
В случае с заполнением DataSet с помощью метода Fill? для решения проблемы, необходимо добавить перед вызовом метода Fill строку da.AcceptChangesDuringFill = false; (где da – экземпляр DataAdapter).
Выполнение процесса (Workflow) из Silverlight при использовании библиотеки SilverCrmSoap
private void ExecuteWorkflow(Guid entityId, Guid workflowId)
{
var request = new OrganizationRequest
{
RequestName = "ExecuteWorkflow",
Parameters = new ParameterCollection
{
new SilverCrmSoap.CrmSdk.KeyValuePair<string, object> { Key = "EntityId", Value = entityId },
new SilverCrmSoap.CrmSdk.KeyValuePair<string, object> { Key = "WorkflowId", Value = workflowId }
}
};
SilverCrmSoap.Helpers.SoapHelper.BeginExecute(request, delegate(IAsyncResult result)
{
try
{
((IOrganizationService)result.AsyncState).EndExecute(result);
}
catch (Exception ex)
{
HtmlPage.Window.Alert("Ошибка выполнения Workflow!");
}
});
}
Получение метаданных сущности в Silverlight
SilverCrmSoap.Helpers.SoapHelper.BeginExecuteRetrieveEntity("new_agreement", delegate(IAsyncResult result)
{
try
{
var response = ((IOrganizationService)result.AsyncState).EndExecute(result);
var entityMetadata = ((EntityMetadata)response["EntityMetadata"]);
...
}
catch (Exception ex)
{
...
}
});
Для доступа к данным используется библиотека SilverCrmSoap.
Ошибка 2103 “Недопустимое или неправильно сформированное приложение: проверьте манифест”
Ошибка Silverlight-приложения:
(по-русски)
SCRIPT5022: Unhandled Error in Silverlight Application Code: 2103 Category: InitializeError Message: Недопустимое или неправильно сформированное приложение: проверьте манифест
(по-английски)
SCRIPT5022: Unhandled Error in Silverlight Application Code: 2103 Category: InitializeError Message: Invalid or malformed application: Check manifest
По-поводу данной ошибки в интернете можно найти только информацию о том, что она возникает по причине не указанного или некорректного Startap Object.
Однако, практика показала, что данная ошибка может быть еще по одной причине – некорректный HTML-файла.
В попытке побороть кэширование Silverlight-приложения, HTML-файл был изменен следующим образом:
...
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="App.xap?ver=1.01"/>
...
</object>
Т.е. к имени файла приложения добавлен параметр с номером версии. Проблема оказалась в точке в номере версии. Именно она вызывала ошибку. Кроме того ошибку вызывал любой символ кроме цифры. Стоило убрать точку, как приложение заработало.
Причина такого поведения непонятна.
DatePicker Binding и пустое значение
Есть элемент управления DatePicker с которым связано некое свойство BirthDate типа DateTime.
<sdk:DatePicker SelectedDate="{Binding Path=BirthDate, Mode=TwoWay}" />
Данная связь будет работать только пока значение DatePicker не пустое. В случае очистки значения элемента управления это пустое значение не будет передано свойству и свойство будет содержать свое прежнее значение.
Происходит это потому, что при очистке значения DatePicker его свойство SelectedDate получает значение null, а в нашем примере свойство BirthDate не может иметь нулевое значение.
Решение проблемы очевидно — необходимо объявить свойство BirthDate как Nullable, то есть объявление свойства должно выглядеть таким образом:
public DateTime? BirthDate { get; set; }
Конвертер bool<->Visibility
Конвертер для преобразования значения булева типа к типу параметра Visibility элемента управления.
using System;
using System.Windows;
using System.Windows.Data;
namespace BE.Silverlight.UI.Converters
{
/// <summary>
/// Конвертер позволяет преобразованть булево значение к значению свойства Visibility элемента управления.
/// </summary>
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (bool)value == true ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (Visibility)value == Visibility.Visible;
}
}
}
JSON + Веб-сервис + JavaScript
Взаимодействие JavaScript c Веб-сервисом с использованием формата JSON.
Код ASPX-страницы
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "POST",
url: "WebService1.asmx/GetEmployees",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
var employees = JSON.parse(msg.d);
var content = [];
content.push('<table>');
for (var i = 0; i < employees.length; i++) {
content.push('<tr><td>');
content.push(employees[i].Name);
content.push('</td><td>');
content.push(employees[i].ID);
content.push('</td><td>');
content.push(employees[i].Age);
content.push('</td></tr>');
}
content.push('</table>');
$('#Content').append(content.join(''));
},
error: function (msg) {
alert("Ошибка! " + msg);
}
});
});
</script>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<div id="Content"></div>
</asp:Content>
Код Веб-сервиса
using System.Collections.Generic;
using System.Web.Script.Services;
using System.Web.Services;
namespace WebApplication1
{
[WebService(Namespace = "http://buseng.ru/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class WebService1 : WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetEmployees()
{
var employee1 = new Employee { Name = "Pini", ID = "111", Age = "30" };
var employee2 = new Employee { Name = "Yaniv", ID = "Cohen", Age = "31" };
var employee3 = new Employee { Name = "Yoni", ID = "Biton", Age = "20" };
var employees = new List { employee1, employee2, employee3 };
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var jsonStr = serializer.Serialize(employees);
return jsonStr;
}
}
public class Employee
{
public string Name { get; set; }
public string Age { get; set; }
public string ID { get; set; }
}
}
В результате выполнения JS-кода, при загрузке страницы будет произведен запрос к сервису и оттуда получены данные о сотрудниках в формате JSON. Эти данные потом будут отображены в виде таблицы:
| Pini | 111 | 30 |
| Yaniv | Cohen | 31 |
| Yoni | Biton | 20 |
Источники
- Формировании JSON-кода
http://blogs.microsoft.co.il/blogs/pini_dayan/archive/2009/03/12/convert-objects-to-json-in-c-using-javascriptserializer.aspx - Запрос JSON-данных из веб-сервиса
http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/ - Работа с JSON с помощью JavaScript
http://www.json.org/js.html
Ошибка “Не удалось завершить эту операцию. Повторите попытку. 0×80004005″ в SharePoint и правила построения запросов с “Or”
Запрос для выбора записей (задач), назначенных на некоторый круг пользователей и не являющихся завершенными:
<Query>
<Where>
<And>
<Or>
<Includes>
<FieldRef Name='AssignedTo' />
<Value Type='Lookup'>user01</Value>
</Includes>
<Includes>
<FieldRef Name='AssignedTo' />
<Value Type='Lookup'>user02</Value>
</Includes>
<Includes>
<FieldRef Name='AssignedTo' />
<Value Type='Lookup'>user03</Value>
</Includes>
</Or>
<Neq>
<FieldRef Name='_x0421__x043e__x0441__x0442__x04' />
<Value Type='Text'>Завершена</Value>
</Neq>
</And>
</Where>
</Query>
Данный запрос возвратит ошибку “Не удалось завершить эту операцию. Повторите попытку. 0×80004005“.
Запрос выглядит довольно правдоподобным и так сразу и не скажешь в чем причина ошибки. Однако, причина довольно банальна – запрос не верен, так как оператор Or может принимать только два условия для сравнения (а в запросе их три). Кому из разработчиков CAML пришла в голову идея сделать именно так (ведь это откровенный бред!) не известно, но факт остается фактом – корректный запрос в данному случае должен выглядеть так:
<Query>
<Where>
<And>
<Or>
<Includes>
<FieldRef Name='AssignedTo' />
<Value Type='Lookup'>user01</Value>
</Includes>
<Or>
<Includes>
<FieldRef Name='AssignedTo' />
<Value Type='Lookup'>user02</Value>
</Includes>
<Includes>
<FieldRef Name='AssignedTo' />
<Value Type='Lookup'>user03</Value>
</Includes>
</Or>
</Or>
<Neq>
<FieldRef Name='_x0421__x043e__x0441__x0442__x04' />
<Value Type='Text'>Завершена</Value>
</Neq>
</And>
</Where>
</Query>
Дабы избежать подобных ошибок и упростить себе работу по построению запросов на просторах интернета найден программа U2U CAML Query Builder for SharePoint 2003 and SharePoint 2007 (Windows Version).
Для программного создания подобных условий пришлось написать такой вот метод:
// [C#]
private static string CreateOrLookupConditions(string comparisonOperator, string fieldName, string[] wssValues)
{
if (wssValues == null || wssValues.Length < 1)
return string.Empty;
var tpl = "<" + comparisonOperator + "><FieldRef Name='" + fieldName + "' /><Value Type='Lookup'>{0}</Value></" + comparisonOperator + ">";
var conditionString = string.Format(tpl, wssValues[0]);
if (wssValues.Length == 1)
return conditionString;
for (var i = 1; i < wssValues.Length; i++)
conditionString = "<Or>" + conditionString + string.Format(tpl, wssValues[i]) + "</Or>";
return conditionString;
}
// Использование
var users = new string[] { "user01", "user02", "user03" };
var conditions = CreateOrLookupConditions("Includes", "AssignedTo", users);
Подключение к удаленному SQL-серверу из SQL-запроса
-- Отключение от удаленного сервера EXEC sp_droplinkedsrvlogin 'MyRemoteServer', NULL GO -- Подключение удаленного сервера IF NOT EXISTS(SELECT name FROM sys.servers WHERE name = 'MyRemoteServer') EXEC sp_addlinkedserver 'MyRemoteServer', N'SQL Server' GO -- Авторизация на удаленном сервере EXEC sp_addlinkedsrvlogin @rmtsrvname = 'MyRemoteServer', @useself = 'false', @rmtuser = 'MyRemoteServerUserName', @rmtpassword = 'MyRemoteServerUserPassword' GO -- Выполнение запроса к удаленной базе SELECT * FROM MyRemoteServer.master.dbo.MyTable